使用printf将双字节字符串格式化为单字节字符串时:
printf("%ls\n", L"s:\\яшертыHello"); // %ls for a wide string (%s varies meaning depending on the project's unicode settings).
显然,有些字符不能表示为ascii字符,所以有时候我会看到双字节字符变成'?'的行为。标记字符。但是,这似乎取决于特定的角色。对于上面的printf,输出为:
s:\
我希望我能得到类似的东西:
s:\??????Hello
我担心我已经丢失了这个例子,但是当我遇到unicode字符时,我想一个字符串,用'?'替换第一个字符串然后放弃了其余的。
所以,我的问题是,当您将宽字符串格式化为单字节字符串时应该会发生什么。这里的文档:http://msdn.microsoft.com/en-us/library/hf4y5e3w.aspx说“字符显示到第一个空字符”。但是,我没有看到。这是printf中的一个错误,还是我在某个地方看到的行为,如果有的话,在哪里。
感谢您的帮助。
更新
感谢人们给我的答案,让我选择使用printf。我将改用另一种方法,但出于好奇,我真的很感兴趣为什么printf没有可靠的记录行为。看起来好像它的实施者不顾一切地使它不起作用。
答案 0 :(得分:12)
我希望你的代码可以工作 - 它可以在Linux上运行 - 但它依赖于语言环境。这意味着您必须设置语言环境,并且您的语言环境必须支持使用的字符集。这是我的测试程序:
#include <locale.h>
#include <stdio.h>
int main()
{
int c;
char* l = setlocale(LC_ALL, "");
if (l == NULL) {
printf("Locale not set\n");
} else {
printf("Locale set to %s\n", l);
}
printf("%ls\n", L"s:\\яшертыHello");
return 0;
}
这是一个执行跟踪:
$ env LC_ALL=en_US.utf8 ./a.out
Locale set to en_US.utf8
s:\яшертыHello
如果它说没有设置区域设置或设置为“C”,那么您没有得到预期的结果是正常的。
修改:查看this question的答案,了解相当于Windows的en_US.utf8。
答案 1 :(得分:5)
在C ++中,我通常使用std::stringstream
来创建格式化文本。我还实现了一个自己的运算符来使用Windows函数进行编码:
ostream & operator << ( ostream &os, const wchar_t * str )
{
if ( ( str == 0 ) || ( str[0] == L'\0' ) )
return os;
int new_size = WideCharToMultiByte( CP_UTF8, 0, str, -1, NULL, NULL, NULL, NULL );
if ( new_size <= 0 )
return os;
std::vector<char> buffer(new_size);
if ( WideCharToMultiByte( CP_UTF8, 0, str, -1, &buffer[0], new_size, NULL, NULL ) > 0 )
os << &buffer[0];
return os;
}
此代码转换为UTF-8。对于其他可能性,请检查:WideCharToMultiByte
。