c++ - 如何知道 std::string 是否编码正确?

标签 c++ string stl

在我的程序中,我从另一个从不同来源读取字符串的函数得到一个 std::string 值,这里的字符串总是包含非 ASCII 字符。

我正在使用 Visual Studio 调试程序。有时当字符串内容在VS调试器中看起来是正确的,那么下一步就可以了(例如使用这个字符串作为输入和输出的目录)。但有时字符串内容看起来不正确,导致下一步出错。

目前我使用QString作为将“incorect”字符串转换为“correct”字符串的桥梁,代码如下。

// get string from somewhere else, sometimes correct sometimes incorrect
string str = getString(); 
QString strQ = QString::fromStdString(str);
str = string(strQ.toLocal8bit);

但有时 str 在转换之前就已经“正确”了,在这种情况下,如果我用上面的代码转换它,它就会出错。

所以我想这里的问题是我怎么知道 std::string 是否有正确的编码?因为我不能总是通过眼睛来判断。

是的,编码是 Stack Overflow 上广泛讨论的话题,但我仍然找不到合适的解决方案。

附言 正确的字符串值在 VS 调试器中看起来像 孙夏^4735,不正确的字符串值看起来像 ????

最佳答案

您必须检查该字符串是否已采用 UTF-8 编码。类似于以下代码(从未测试过,请使用它来激发您的灵感)。

#include <string>

enum DetectedCoding {ASCII, UTF8, OTHER};

DetectedCoding DetectEncoding(const std::string & s)
{
  const char * cs = s.c_str();
  DetectedCoding d = ASCII;
  while (*cs)
  {
    unsigned char b = (unsigned char)*(cs++);
    if (b & 0x80) { // not a plain ASCII character
      // if the string is already UTF8 encoded, then it must conform to a multibyte sequence standard. Let's verify it
      if (b < 0xC0) // first of all, b must start with 11
        return OTHER; //  no multibyte sequence starts with 10xxxxxx
      // now we expect a number of continuation bytes, depending on the number of ones following the 11
      size_t nCont = 0;
      if (b < 0xE0) // two bytes sequence: 110xxxxx 10xxxxxx
        nCont = 1;
      else if (b < 0xF0) // three bytes sequence: 1110xxxx 10xxxxxx 10xxxxxx
        nCont = 2;
      else if (b < 0xF8) // four bytes sequence: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
        nCont = 3;
      else if (b < 0xFC) // five bytes sequence: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
        nCont = 4;
      else if (b < 0xFE) // six bytes sequence: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
        nCont = 5;
      else
        return OTHER; //  no multibyte sequence starts with 1111111x
      while (nCont--)
        if (((unsigned char)*(cs++) & 0xC0) != 0xC0) // in case string ends, 0 is found so the following test prevents us from illegal memory access
          return OTHER; //  each continuation byte must starts with 10xxxxxx
      d = UTF8;
    }
  }
  return d;
}

关于c++ - 如何知道 std::string 是否编码正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50742542/

相关文章:

c++ - 抛出错误 "as ‘p’ 中的包装函数未在此范围内声明”

regex - 从 R 中的字符串中删除所有特殊字符?

c++ - 如何配置 std::priority_queue 以忽略重复项?

C++ 对结构 vector 进行排序

c++ - 检查某个位置的元素是否存在(设置)在 STL vector 中

c++ - 如何在 C++ 中正确地静态转换 vector ?

c++ - 使用 omp_set_num_threads() 将线程数设置为 2,但 omp_get_num_threads() 返回 1

c++ - 线程常量错误 C++

java - Android 通过蓝牙连接到 Arduino。应用程序不会发送字符串

c++ - 在 while 循环中使用字符串查找和替换时的 std::out_of_range