我正在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

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

1回复

MultiByteToWideChar将(°)度符号转换为。

我正在尝试将字符串从ANSII转换为Wide char。 我正在使用CA2W(string,CP_UTF8)内部使用MultiByteToWideChar 。 调试时显示MultiByteToWideChar将°度符号转换为 。 有关如何解决此问题的任何建议?
5回复

将字符串转换为LPWSTR [重复]

这个问题在这里已有答案: 如何在C ++(Unicode) 6答案 中将std :: string转换为LPCWSTR 我很难将字符串转换为LPWSTR因此我可以使用PathStripToRoot()函数。 好吧,一个MSDN文档说我需要LPTSTR变量( h
2回复

如何将Visual Studio项目从使用宽字符串转换为普通字符串

当我创建我的visual studio项目时,它默认强制我对所有带字符串的函数使用宽字符串。 例如,MessageBox()采用LPCWSTR而不是const char *。 虽然我知道它对于多语言和便携式应用程序来说非常棒,但对于我简单的小应用程序来说,它是完全没必要的。 坦率地说,在我
2回复

Unicode代码页1200、1201、12000、12001的MultiByteToWideChar

我有一个函数,可以将字符串从各种编码转换为Windows内部使用的Unicode-16。 为此,我使用了MultiByteToWideChar API。 但是我发现以下内容: 以下Unicode代码页失败,错误代码为ERROR_INVALID_PARAMETER (87):
3回复

MultiByteToWideChar用垃圾终止输出缓冲区,但未报告任何错误。 为什么?

前几天开发程序时,我不得不将ASCII字符串转换为Unicode字符串。 顺便说一下,我正在Windows和Visual Studio 2012上工作。 我注意到Win32函数MultiByteToWideChar有一些奇怪的行为,我MultiByteToWideChar 。 我在下面编写
2回复

c ++字符串类型混乱

我在.cpp程序中包含以下文件: 不过,当我写的时候 编译器提示以下错误: C2664:'size_t strlen(const char *)':无法将参数1从'LPCTSTR'转换为'const char *'指向的类型不相关; 转换需要reinterpret_c
2回复

如何在字符级别处理Unicode字符串?

有时在字符级别上不可避免地要操纵字符串。 在这里,我有一个为基于ANSI / ASCII的字符串编写的函数,该函数仅用LF替换CR / LF序列,也用LF替换CR。 我们之所以使用它,是因为由于各种文本或电子邮件程序使传入的文本文件混乱而常常使行尾变得笨拙,因此我需要它们采用一致的格式,
3回复

wostringstream,Ascii,Unicode,Win32和整数串联到字符串

我正在编写一个使用Win32 API的库,并且希望能够将其编译为ASCII和Unicode(宽字符为type ),并且正在生成一个内部类名(读取:WinAPI“ class”),我在字符串后附加一个整数,以为各种Windows函数创建唯一的类名。 使用的变量的定义: 有问题的功能:
3回复

将unicode字符串复制到剪贴板不起作用

我不知道为什么这段代码无法正常工作:
5回复

如何打印__FILE__正确扩展的字符串?

考虑这个程序: 根据文件的名称,该程序可以工作 - 或不工作。 我面临的问题是我想以编码安全的方式打印当前文件的名称。 但是,如果文件包含无法在当前代码页中表示的有趣字符,编译器会发出警告(这是正确的): 我该如何解决这个问题? 我想将__FILE__给出的字符串存储在例如