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

Sco*_*ham 8 c c++ unicode visual-studio-2010

使用printf将双字节字符串格式化为单字节字符串时:

printf("%ls\n", L"s:\\??????Hello");   // %ls for a wide string (%s varies meaning depending on the project's unicode settings).
Run Code Online (Sandbox Code Playgroud)

显然,有些字符不能表示为ascii字符,所以有时我看到双字节字符变成'?'的行为.标记字符.但是,这似乎取决于特定的角色.对于上面的printf,输出是:

s:\
Run Code Online (Sandbox Code Playgroud)

我希望我可以得到类似的东西:

s:\??????Hello
Run Code Online (Sandbox Code Playgroud)

我担心我已经失去了这个例子,但是当我遇到unicode字符时,我想一个字符串,用'?'替换第一个字符串 然后放弃了其余的.

所以,我的问题是,当您将宽字符串格式化为单字节字符串时应该发生什么.这里的文档:http://msdn.microsoft.com/en-us/library/hf4y5e3w.aspx说"字符显示到第一个空字符".但是,我没有看到.这是printf中的一个错误,还是我在某处记录的行为,如果有的话,在哪里.

谢谢你的帮助.

UPDATE

感谢人们给我替代使用printf的答案.我将改为另类,但出于好奇,我真的很感兴趣为什么printf没有可靠的记录行为.看起来好像它的实现者竭尽全力使它不起作用.

APr*_*mer 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;
}
Run Code Online (Sandbox Code Playgroud)

这是一个执行跟踪:

$ env LC_ALL=en_US.utf8 ./a.out
Locale set to en_US.utf8
s:\??????Hello
Run Code Online (Sandbox Code Playgroud)

如果它表示未设置区域设置或设置为"C",则通常无法获得预期的结果.

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


Nas*_*zta 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;
}
Run Code Online (Sandbox Code Playgroud)

此代码转换为UTF-8.对于其他可能性检查:WideCharToMultiByte.