我正在std::string上构建一个合成的UTF-8字符串,并尝试使用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; 

事实证明, MultiByteToWideChar并没有将str为简单的L“ABC”字符串,而是将每个字符转换为wchar_t - 这意味着对'A' + char(0)不会转向L'A'而是转向L'A' + L'\\0'

我在这里做错了什么,或者这是MultiByteToWideChar的预期行为?

===============>>#1 票数:5 已采纳

std::string str;
str += 'A'; 
str += char(0);
str += 'B';
str += char(0);
str += 'C';
str += char(0);
str += char(0);
str += char(0);

这不是产生UTF-8编码的字符串! 它正在生成一个UTF-16编码的字符串。

int sizeNeeded = MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), NULL, 0) + 1;

您告诉MultiByteToWideChar()str的原始字节解释为UTF-8,即使它实际上没有以UTF-8编码。

Unicode代码点U+0000在UTF-8中有效(编码为0x00 ),因此str每个0x00字符将被解释为代码点U+0000 ,其余字符将被解释为原样,因为它们都小于U+0080 因此,“UTF-8”字符串中没有多字节序列,只有单字节序列。

最终得到一个包含以下代码点的UTF-16 wstring

0x41 -> U+0041 
0x00 -> U+0000
0x42 -> U+0042
0x00 -> U+0000
0x43 -> U+0043
0x00 -> U+0000
0x00 -> U+0000
0x00 -> U+0000

如果您将str编码为UTF-8,然后将其解释为UTF-8,那么您最终会得到正确的UTF-16 wstring

std::string str;
str += 'A'; 
str += 'B';
str += 'C';
str += char(0);

0x41 -> U+0041 
0x42 -> U+0042
0x43 -> U+0043
0x00 -> U+0000

或者,如果您将str编码为UTF-16并将其解释为UTF-16(您无法使用MultiByteToWideChar() ,则必须手动执行),您仍然会得到一个包含UTF-16 wstring的UTF-16 wstring正确的代码点:

std::string str;
str += 'A'; 
str += char(0);
str += 'B';
str += char(0);
str += 'C';
str += char(0);
str += char(0);
str += char(0);

0x41 0x00 -> U+0041 
0x42 0x00 -> U+0042
0x43 0x00 -> U+0043
0x00 0x00 -> U+0000

===============>>#2 票数:3

您正在错误地编码字符串"ABC" 空字符是虚假的。 ASCII范围中的字符以UTF-8中的单个八位字节编码。

像这样编码:

std::string str;
str += 'A'; 
str += 'B':
str += 'C';
str += 0;

虽然

std::string str = "ABC";

更简单。

  ask by David Haim translate from so

未解决问题?本站智能推荐: