免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 14731 | 回复: 7
打印 上一主题 下一主题

为什么printf可以打印中文,而wprintf却一定要setlocale才能正确打印? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-03-31 18:47 |只看该作者 |倒序浏览
我的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也能工作?

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
2 [报告]
发表于 2012-03-31 23:33 |只看该作者
要将unicode转化为本地字符显示呀,不设置正确的locale就不能正确的转化

论坛徽章:
0
3 [报告]
发表于 2012-04-01 11:55 |只看该作者
bruceteen 发表于 2012-03-31 23:33
要将unicode转化为本地字符显示呀,不设置正确的locale就不能正确的转化


wprintf打印的一定是unicode么? 而不会是当前代码也代表的语言?
而为什么printf不用setlocale就能打印中文,wprintf反而需要我显示的调用setlocale,它默认不能正确的setlocale当前的语言么?

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
4 [报告]
发表于 2012-04-01 12:04 |只看该作者
只要printf的文字编码和显示平台(例如当前的控制台)的代码页不一致,就需要 setlocale
但一般两者是一致的

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
5 [报告]
发表于 2012-04-01 12:23 |只看该作者
在windows上,我设定cmd /u为unicode,还是搞不定
调试代码,发现VC的printf还是会先将 unicode字符转化为多字节字符(wctomb_s)

论坛徽章:
0
6 [报告]
发表于 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编码解释,最后当然就乱码了。

论坛徽章:
0
7 [报告]
发表于 2012-04-01 22:06 |只看该作者
liwangli1983 发表于 2012-04-01 12:42
这个问题涉及到一个字符,他在源代码时是以什么形式(或者说编码格式)存的,在编译好的二进制文件中是以什 ...


很清晰的解释啊!

论坛徽章:
0
8 [报告]
发表于 2012-04-01 22:07 |只看该作者
bruceteen 发表于 2012-04-01 12:23
在windows上,我设定cmd /u为unicode,还是搞不定
调试代码,发现VC的printf还是会先将 unicode字符转化为 ...

多谢提示!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP