为什么printf格式的unicode参数没有?

使用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中的一个错误,还是我在某处看到的行为,如果有的话,在哪里。

谢谢你的帮助。

UPDATE

感谢人们给我替代使用printf的答案。 我将改为另一种选择,但出于好奇,我真的很感兴趣为什么printf没有可靠的记录行为。 看起来好像它的实现者不顾一切地使它不起作用。

我希望你的代码可以运行 – 它可以在Linux上运行 – 但它依赖于语言环境。 这意味着您必须设置区域设置,并且您的区域设置必须支持使用的字符集。 这是我的测试程序:

 #include  #include  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”,则通常无法获得预期的结果。

编辑:查看此问题的答案,相当于Windows的en_US.utf8。

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