Dav*_*aim 2 c++ unicode winapi
我正在构建一个合成的UTF-8字符串std::string并尝试将其转换为MultiByteToWideChar.这是我的代码:
std::string str;
str += 'A';
str += char(0);
str += 'B';
str += char(0);
str += 'C';
str += char(0);
str += char(0);
str += char(0);
std::wstring wstr;
if (str.empty()){
wstr = L"";
}
int sizeNeeded = MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), NULL, 0) + 1;
std::wstring wstrTo(sizeNeeded, 0);
MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), &wstrTo[0], sizeNeeded);
wstr = wstrTo;
std::wcout << wstr;
Run Code Online (Sandbox Code Playgroud)
事实证明,这MultiByteToWideChar并不是str简单地转向L"ABC"字符串,而是将每个字符转变为wchar_t- 意味着该对'A' + char(0)不会转向L'A'但是L'A' + L'\0'
我在这里做错了什么或这是预期的行为MultiByteToWideChar?
std::string str;
str += 'A';
str += char(0);
str += 'B';
str += char(0);
str += 'C';
str += char(0);
str += char(0);
str += char(0);
Run Code Online (Sandbox Code Playgroud)
这不是产生UTF-8编码的字符串!它正在生成一个UTF-16编码的字符串.
int sizeNeeded = MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), NULL, 0) + 1;
Run Code Online (Sandbox Code Playgroud)
您告诉MultiByteToWideChar()我们将原始字节解释str为UTF-8,即使它实际上没有以UTF-8编码.
Unicode代码点U+0000在UTF-8中有效(它被编码为0x00),因此每个0x00字符str都将被解释为代码点U+0000,其余字符将按原样解释,因为它们都小于U+0080.因此,"UTF-8"字符串中没有多字节序列,只有单字节序列.
最终得到wstring包含以下代码点的UTF-16 :
0x41 -> U+0041
0x00 -> U+0000
0x42 -> U+0042
0x00 -> U+0000
0x43 -> U+0043
0x00 -> U+0000
0x00 -> U+0000
0x00 -> U+0000
Run Code Online (Sandbox Code Playgroud)
如果您str正确编码为UTF-8,然后将其解释为UTF-8,您最终会得到正确的UTF-16 wstring:
std::string str;
str += 'A';
str += 'B';
str += 'C';
str += char(0);
Run Code Online (Sandbox Code Playgroud)
0x41 -> U+0041
0x42 -> U+0042
0x43 -> U+0043
0x00 -> U+0000
Run Code Online (Sandbox Code Playgroud)
或者,如果您将str编码保留为UTF-16并将其解释为UTF-16(您无法使用MultiByteToWideChar()它,则必须手动执行),您仍然会得到wstring包含正确代码点的UTF-16 :
std::string str;
str += 'A';
str += char(0);
str += 'B';
str += char(0);
str += 'C';
str += char(0);
str += char(0);
str += char(0);
Run Code Online (Sandbox Code Playgroud)
0x41 0x00 -> U+0041
0x42 0x00 -> U+0042
0x43 0x00 -> U+0043
0x00 0x00 -> U+0000
Run Code Online (Sandbox Code Playgroud)