c++ - 为什么在 winapi 中转换 UTF16 -> UTF8 -> UTF16 后文件名有不同的字节?

标签 c++ c winapi encoding utf-8

我有下一个文件: enter image description here

我使用 ReadDirectoryChangesW用于读取当前文件夹中的更改。 我得到了这个文件的路径:L"TEST Ӡ⬨☐.ipt":

enter image description here

接下来,我想将其转换为 utf8 并返回:

std::string wstringToUtf8(const std::wstring& source) {
  const int size = WideCharToMultiByte(CP_UTF8, 0, source.data(), static_cast<int>(source.size()), NULL, 0, NULL, NULL);
  std::vector<char> buffer8(size);
  WideCharToMultiByte(CP_UTF8, 0, source.data(), static_cast<int>(source.size()), buffer8.data(), size, NULL, NULL);
}

std::wstring utf8ToWstring(const std::string& source) {
  const int size = MultiByteToWideChar(CP_UTF8, 0, source.data(), static_cast<int>(source.size()), NULL, 0);
  std::vector<wchar_t> buffer16(size);
  MultiByteToWideChar(CP_UTF8, 0, source.data(), static_cast<int>(source.size()), buffer16.data(), size);
}

int main() {
    // Some code with ReadDirectoryChangesW and 
    // ...
    // std::wstring fileName = "L"TEST Ӡ⬨☐.ipt""
    // ...

    std::string filenameUTF8 = wstringToUtf8(fileName);
    std::wstring filename2 = utf8ToWstring(filenameUTF8);
    assert(filenameUTF8 == filename2); // FAIL!
    return 0;
}

但我捕获了断言。 文件名2: enter image description here

不同位:[29]

为什么?

最佳答案

57216 似乎属于代理对范围,在 UTF-16 中用于对非 BMP 代码点进行编码。它们需要成对给出,否则解码不会为您提供正确的代码点。

65533 是解码器给出的一个特殊错误字符,因为缺少其他代理项。

换句话说:您的原始字符串不是有效的 UTF-16 字符串。

More info on Wikipedia .

关于c++ - 为什么在 winapi 中转换 UTF16 -> UTF8 -> UTF16 后文件名有不同的字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34743801/

相关文章:

c++ - 使用 CreateFile 打开 Display 时的正确路径是什么?

c++ - 如何使用 ShellExecuteEx 确保 exe 启动

c++ - 为什么类的析构函数被调用两次?

java - 使用 STL 与 NDK 的运行时链接错误

c - 执行USB/Pendrive中编译的C

c - 有没有使用 bool 值的标准方法?因为我的代码出错了

winapi - 使用 OpenGL 和 Gdi+ 的 GetDC、ReleaseDC、CS_OWNDC

c++ - 检索现有着色器属性时,glGetAttribLocation 返回 -1

c++ - c++多重继承的理解

c - 如何测量 cpu 时间和挂钟时间?