C++ 什么';是printf(“%s”)、printf(“%ls”)、wprintf(“%s”)和wprintf(“%ls”)之间的区别吗?
考虑以下示例程序:C++ 什么';是printf(“%s”)、printf(“%ls”)、wprintf(“%s”)和wprintf(“%ls”)之间的区别吗?,c++,unicode,printf,widechar,C++,Unicode,Printf,Widechar,考虑以下示例程序: #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()
#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和2的答案在文档中。任何一套好的文档都可以。他们说这很好 至于3,语言标准没有规定字符串的任何特定编码,也没有规定
wchar\u t
的任何特定大小。您需要查阅实现文档,而不是语言本身的文档(尽管很少建议编写依赖于实现的代码)。您需要执行以下操作:
wprintf(L"3 %hs \n", narrowstr.c_str());
wprintf(L"4 %s \n", widestr.c_str());
为什么??因为对于printf
,%s表示窄字符字符串。对于wprintf
,%ls表示宽
但是,对于wprintf
,%s表示宽,%ls表示宽本身%hs意味着狭窄(对两者而言)。对于printf
,%s,以这种方式表示%hs
在VC++/Windows上,
%S
(大写字母S)会扭转这种效果。因此,printf(“%S”)
表示宽,wprintf(“%S”)
表示窄。这对于\u tprintf
非常有用。请注意,您使用的是C流。C流有一种非常特殊的特性,称为“定向”。溪流要么是无方向的,要么是宽的,要么是窄的。方向由对任何特定流的第一次输出决定(有关C I/O流的摘要,请参阅)
在您的例子中,stdout
开始时没有方向,通过执行第一个printf
,您将其设置为窄值。一旦变窄,它就会被卡住,并且wprintf
失败(检查其返回代码!)。更改C流的唯一方法是freopen
it,这对stdout不太起作用。这就是为什么3和4没有打印出来
1和3之间的区别在于1是一个使用窄字符串转换说明符%s的窄输出函数:它从字符数组读取字节,并将字节发送到字节流。3是一个具有窄字符串转换说明符%s的宽输出函数:它首先从字符数组中读取字节,然后将其读入wchar\t
s,然后将wchar\t
s发送到宽流中,然后,wc将它们转换成字节或多字节序列,然后通过write
最后,如果widestr在utf16中,那么您必须使用Windows,并且所有赌注都已取消;在这个平台上,除了ASCII之外,几乎不支持任何东西。您也可以放弃并使用WinAPI(对于一些Unicode的事情,您可以使用标准C++11,甚至可以使用神奇的单词\u setmode(\u fileno(stdout),\u O\u U16TEXT);
,已经讨论了很多次了)等等!为什么它甚至不打印数字??您是否检查了wprintf是否工作?“WideTR在utf16中”表示您使用的是Windows(对Unicode更友好的系统使用UTF-32作为宽字符串的默认值)。如果你想在Windows系统上使用标准C++或C做任何事情,你可以跳过很多神秘的箍,你也可以放弃并使用WINAPII。不要屈服于微软的愚蠢。省去你的痛苦,编写你自己的字符串库。看在上帝的份上,不要使用windows宏转换和其他疯狂的操作,相信我,这太可怕了,在混乱中,各种各样的错误悄悄地出现了。#4可能没有打印出来,因为你的程序在#3上崩溃了%ls
是打印wchar\u t
字符串的最便捷的方式,可从printf
和wprintf
两种方式工作。你应该避免使用<代码> %s>代码>,因为它的Visual C++解释与C99/C++ 11标准完全相反。
wprintf(L"3 %hs \n", narrowstr.c_str());
wprintf(L"4 %s \n", widestr.c_str());