Chinaunix

标题: 为什么printf可以打印中文,而wprintf却一定要setlocale才能正确打印? [打印本页]

作者: moonsister02    时间: 2012-03-31 18:47
标题: 为什么printf可以打印中文,而wprintf却一定要setlocale才能正确打印?
我的VC工程不论是MBCS还是Unicode,发现printf总是能正确打印char*表示的中文。

而wprintf打印wchar_t*的中文,必须要先设置setlocal(LC_ALL,"chs")才行,否则打印一堆乱码。

我的问题是:
(1)为什么printf能正常打印中文,而不是按字节打印出一堆ascii字符。
(2)wprintf既然是打印L()包裹的中文,那么它为什么不能工作?我当前就是中文系统啊,本机运行,没有更换到英文系统上。那么还要在此之前setlocale我总感觉有点多次一举啊。

大侠解释一下吧 !

  1.    setlocale(LC_ALL,"chs");
  2.    string s="你好abc";
  3.    wstring ws=L"你好abc";
  4.    printf("%s\n",s.c_str());
  5.    wprintf(L"%s\n",ws.c_str());
复制代码
为什么要设置setlocale才能正确的wprintf? 已经知道了是宽字符的,为何还要设置代码页? 为什么string/printf就不需要设置locale也能工作?

作者: bruceteen    时间: 2012-03-31 23:33
要将unicode转化为本地字符显示呀,不设置正确的locale就不能正确的转化
作者: moonsister02    时间: 2012-04-01 11:55
bruceteen 发表于 2012-03-31 23:33
要将unicode转化为本地字符显示呀,不设置正确的locale就不能正确的转化


wprintf打印的一定是unicode么? 而不会是当前代码也代表的语言?
而为什么printf不用setlocale就能打印中文,wprintf反而需要我显示的调用setlocale,它默认不能正确的setlocale当前的语言么?
作者: bruceteen    时间: 2012-04-01 12:04
只要printf的文字编码和显示平台(例如当前的控制台)的代码页不一致,就需要 setlocale
但一般两者是一致的
作者: bruceteen    时间: 2012-04-01 12:23
在windows上,我设定cmd /u为unicode,还是搞不定
调试代码,发现VC的printf还是会先将 unicode字符转化为多字节字符(wctomb_s)
作者: liwangli1983    时间: 2012-04-01 12:42
本帖最后由 liwangli1983 于 2012-04-01 12:43 编辑

这个问题涉及到一个字符,他在源代码时是以什么形式(或者说编码格式)存的,在编译好的二进制文件中是以什么形式存的,以及最后输出的时候输出的是什么编码格式。

如果是普通字符串,那么它在这三者中表现形式是一致的。而宽字符串,却有可能不同。

以linux为例,因为linux下通常使用的字符编码都是utf8,所以源码也是以utf8保存的,对于普通字符串,在编译器编译的过程中,什么也不做,原样将这个编码放到二进制文件中。然后printf输出的时候,也是原样输出。如果接收输出的那个程序(也许是一个shell)支持utf8,那么当然就可以正常显示出来了。如果不支持,就会错乱。

而对于宽字符来说,还以linux为例。源码中依然是utf8,但编译器在编译过程中,会把字符的编码转换成unicode保存在二进制文件中。而输出的形式,取决于你的locale设定了。如果shell支持的是utf8,但你设定的locale是gbk,printf的时候程序就会把unicode转成gbk编码输出,而这边shell却当成utf8编码解释,最后当然就乱码了。
作者: moonsister02    时间: 2012-04-01 22:06
liwangli1983 发表于 2012-04-01 12:42
这个问题涉及到一个字符,他在源代码时是以什么形式(或者说编码格式)存的,在编译好的二进制文件中是以什 ...


很清晰的解释啊!
作者: moonsister02    时间: 2012-04-01 22:07
bruceteen 发表于 2012-04-01 12:23
在windows上,我设定cmd /u为unicode,还是搞不定
调试代码,发现VC的printf还是会先将 unicode字符转化为 ...

多谢提示!




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2