2014-11-08 198 views
10

考虑这个示例程序:printf(“%s”),printf(“%ls”),wprintf(“%s”)和wprintf(“%ls”)有什么区别?

#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 

我想知道:

  1. 为什么3 & 4没有打印
  2. 什么差异在1 & 3和2 & 4.
  3. 它是否有任何区别,如果narrowstr在utf8中而且vasttr在utf16中?
+1

你看了文档?值得注意的是[cstdio](http://www.cplusplus.com/reference/cstdio/)? – 2014-11-08 11:24:57

+0

“vasttr is in utf16”意味着您使用的是Windows(更适合Unicode的系统使用UTF-32作为宽字符串的默认值)。如果你想在WIndows系统上使用标准的C++或C来完成除ASCII以外的任何事情,那么有很多神秘的箍环可以跳转。你也可以投入并使用WinAPI。 – Cubbi 2014-11-13 02:59:23

+0

不要投放到MICROSOFT STUPIDITY。节省自己的痛苦并编写自己的字符串库。对于上帝的爱不要使用Windows宏观转换和其他疯狂,相信我,这是可怕的,并在混乱中各种错误蔓延。 – Owl 2017-05-12 14:38:00

回答

0

1和2的答案在文档中。任何一套好的文档都可以。他们说cppreference是非常好的。

至于3,语言标准没有指定任何特定的字符串编码或任何特定的尺寸wchar_t。你需要参考你的实现文档,而不是语言本身(尽管编写依赖于实现的代码是很不明智的)。

5

你需要做的:

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")意味着狭窄。这对于_tprintf很有用。

+0

这也不打印任何东西。 [链接](http://ideone.com/ZCiDb1) – 2014-11-08 21:02:51

+0

坚持!为什么它甚至不打印数字?你检查过wprintf的作品吗? – Ajay 2014-11-08 21:05:32

5

请注意,您正在使用C流。 C流具有非常特殊的质量,称为“定位”。流是不定向的,宽的或狭窄的。方向是通过任何特定流所发出的第一输出决定(见http://en.cppreference.com/w/cpp/io/c的CI/O流的汇总)

在你的情况,stdout开始时未取向,并通过执行第一printf,你设置它窄。一旦缩小,它会陷入狭窄,并且wprintf失败(检查其返回代码!)。更改C流的唯一方法是freopen它,它不适用于标准输出。这就是为什么3和4没有打印。

1和3之间的区别在于1是使用窄字符串转换说明符%s的窄输出函数:它从char数组读取字节并将字节发送到字节流中。3是一个具有窄字符串转换说明符%s的宽输出函数:它首先从char数组中读取字节并将它们读入wchar_ts,然后将wchar_ts发送到一个宽流中,然后wctomb将它们转换为字节或多字节序列然后用write

将其推送到标准中。最后,如果widestr位于utf16中,则必须使用Windows,并且所有投注都关闭;在该平台上对ASCII以外的任何内容都没有支持。你不妨给并使用WinAPI的(你可以用标准C++ 11的一些Unicode的东西度日,甚至做C的输出,用咒语_setmode(_fileno(stdout), _O_U16TEXT);,一个已经讨论足够多的次数)

相关问题