考虑这个示例程序:
#include <cstdio>
#include <cwchar>
#include <string>
int main()
{
std::string narrowstr = "narrow";
std::wstring widestr = L"wide";
printf("1 %s \n", narrowstr.c_str());
printf("2 %ls \n", widestr.c_str());
wprintf(L"3 %s \n", narrowstr.c_str());
wprintf(L"4 %ls \n", widestr.c_str());
return 0;
}
这个输出是:
1 narrow
2 wide
我想知道:
答案 0 :(得分:9)
你需要这样做:
wprintf(L"3 %hs \n", narrowstr.c_str());
wprintf(L"4 %s \n", widestr.c_str());
为什么呢?因为对于printf
,%s 表示narrow-char-string。对于wprintf
,%ls 表示广泛。
但是,对于wprintf
,%s 意味着广泛,%ls 意味着广泛。 %hs 意味着缩小(两者都有)。对于printf
,%s ,以这种方式只是意味着%hs
在VC ++ / Windows上,%S
(大写S)会扭转效果。因为printf("%S")
它意味着宽,wprintf("%S")
意味着狭窄。这对_tprintf
非常有用。
答案 1 :(得分:5)
请注意,您正在使用C流。 C流具有非常特殊的质量,称为“定向”。流是未定向的,宽的或窄的。方向取决于对任何特定流的第一个输出(有关C I / O流的摘要,请参阅http://en.cppreference.com/w/cpp/io/c)
在您的情况下,stdout
开始无定向,并且通过执行第一个printf
,您将其设置得很窄。一旦变窄,它就会变窄,wprintf
失败(检查其返回代码!)。更改C流的唯一方法是freopen
它,它与stdout不太一样。这就是为什么3和4没有打印的原因。
1和3之间的差异是1是一个窄输出函数,它使用窄字符串转换说明符%s:它从char数组中读取字节并将字节发送到字节流。 3是一个带有窄字符串转换说明符%s的宽输出函数:它首先从char数组中读取字节,然后mbtowc
将它们读入wchar_t
s,然后将wchar_t
s发送到宽流,然后wctomb
将它们转换为字节或多字节序列,然后使用write
最后,如果widestr在utf16中,你必须使用Windows,所有的赌注都关闭;在该平台上,除了ASCII以外的任何东西都很少支持。您也可以放弃并使用WinAPI(您可以使用标准C ++ 11获取某些Unicode内容,甚至使用魔术字_setmode(_fileno(stdout), _O_U16TEXT);
执行此C输出,已经讨论了足够多次)
答案 2 :(得分:0)
问题的答案1和2都在文档中。任何好的文档都可以。他们说cppreference非常好。
对于3,语言标准没有为字符串或wchar_t
的任何特定大小指定任何特定编码。您需要查阅实现的文档,而不是正确的语言(尽管很少编写依赖于实现的代码)。