解决使用VC运行时库函数wprintf和wcount显示中文不正确的问题
2006-11-23 13:58
686 查看
昨天,我测试了C运行时库的Locale方面的函数,发现了一些疑问,好像现在相通了。我的测试代码如下:
[align=left] {[/align]
[align=left]char* paName = "测试中";[/align]
[align=left] wchar_t* pwName = L"测试中";[/align]
[align=left] [/align]
[align=left] printf(paName); //输出为:测试中[/align]
[align=left] wprintf((wchar_t*)paName); //输出为:空[/align]
[align=left] [/align]
[align=left] printf((char*)pwName); //输出为:乱码[/align]
wprintf(pwName); //输出为:空
}
如果将程序改写如下,则输出的结果就不一样了
[align=left] {[/align]
[align=left]char* paName = "测试中";[/align]
[align=left] wchar_t* pwName = L"测试中";[/align]
[align=left] [/align]
[align=left] setlocale(LC_ALL, "chs");[/align]
[align=left] [/align]
[align=left] printf(paName); //输出为:测试[/align]
[align=left] wprintf((wchar_t*)paName); //输出为:空[/align]
[align=left] [/align]
[align=left] printf((char*)pwName); //输出为:乱码[/align]
wprintf(pwName); //输出为:测试
}
从上面两个代码片断可以看出:setlocale()对printf()没有影响,同时对char*的字符串也没有影响。唯一受到影响的是wprintf()这个函数了。我通过调试器查看了paName和pwName的字符,他们分别是:
paName :b2e2 cad4 d6d0 …… 应该是CHS编码(也就是代码页936)
pwName :4b6d d58b 2d4e …… Unicode编码
我昨天的疑问是:wprintf()应该是用来显示Unicode编码的,那么在没有调用setlocale()函数应该能够正常显示pwName所指的字符串,因为pwName所指的字符串正是Unicode编码的字符串;而在调用了setlocale()之后,wprintf()应该是用来显示本地字符串的(在本例中本地代码也就是936),将本地字符串转换成Unicode字符之后再显示,所以不能够将pwName所指的Unicode字符串显示出来。但是,好像结果却是相反的。
今天,我才想通了。我上面的阐述中假设了一个条件:即显示器在显示的时候是显示Unicode字符串的。如果,这个前提条件刚好是相反的:即显示器在显示的时候是显示本地字符串的。那么按照我上面的推理,应该会和测试的结果相一致的。
〔疑问〕按照上面的推理,在分析wprintf((wchar_t*)paName)语句时还像和结果是不一致的。应该在没有使用setlocale()的代码片断中可以正常显示出来的。但是,不知道为什么不是这样?
答:刚才在深入的调试了C运行时库,发现我的想法是正确的,在wprintf()函数里面,调用了WideCharToMultiByte()函数,就是通过当前的Locale将Unicode的字符转换成本地字符。在不使用setlocale()的时候,wprintf()会使用默认的“C”locale判断给定的宽字符是否<255,如果大于255就返回错误,而不会进行显示。这也就是在没有setlocale()的情况下wprintf((wchar_t*)paName)不能显示的真正原因。我觉得,如果wprintf()不进行这种判断而直接将字符串给Console的话,就能够正确显示了。但是,VC++中的wcout就可以在没有设置locale的情况下正确输出paName,可能就是象我说的一样。
测试环境VC8
[align=left] {[/align]
[align=left]char* paName = "测试中";[/align]
[align=left] wchar_t* pwName = L"测试中";[/align]
[align=left] [/align]
[align=left] printf(paName); //输出为:测试中[/align]
[align=left] wprintf((wchar_t*)paName); //输出为:空[/align]
[align=left] [/align]
[align=left] printf((char*)pwName); //输出为:乱码[/align]
wprintf(pwName); //输出为:空
}
如果将程序改写如下,则输出的结果就不一样了
[align=left] {[/align]
[align=left]char* paName = "测试中";[/align]
[align=left] wchar_t* pwName = L"测试中";[/align]
[align=left] [/align]
[align=left] setlocale(LC_ALL, "chs");[/align]
[align=left] [/align]
[align=left] printf(paName); //输出为:测试[/align]
[align=left] wprintf((wchar_t*)paName); //输出为:空[/align]
[align=left] [/align]
[align=left] printf((char*)pwName); //输出为:乱码[/align]
wprintf(pwName); //输出为:测试
}
从上面两个代码片断可以看出:setlocale()对printf()没有影响,同时对char*的字符串也没有影响。唯一受到影响的是wprintf()这个函数了。我通过调试器查看了paName和pwName的字符,他们分别是:
paName :b2e2 cad4 d6d0 …… 应该是CHS编码(也就是代码页936)
pwName :4b6d d58b 2d4e …… Unicode编码
我昨天的疑问是:wprintf()应该是用来显示Unicode编码的,那么在没有调用setlocale()函数应该能够正常显示pwName所指的字符串,因为pwName所指的字符串正是Unicode编码的字符串;而在调用了setlocale()之后,wprintf()应该是用来显示本地字符串的(在本例中本地代码也就是936),将本地字符串转换成Unicode字符之后再显示,所以不能够将pwName所指的Unicode字符串显示出来。但是,好像结果却是相反的。
今天,我才想通了。我上面的阐述中假设了一个条件:即显示器在显示的时候是显示Unicode字符串的。如果,这个前提条件刚好是相反的:即显示器在显示的时候是显示本地字符串的。那么按照我上面的推理,应该会和测试的结果相一致的。
〔疑问〕按照上面的推理,在分析wprintf((wchar_t*)paName)语句时还像和结果是不一致的。应该在没有使用setlocale()的代码片断中可以正常显示出来的。但是,不知道为什么不是这样?
答:刚才在深入的调试了C运行时库,发现我的想法是正确的,在wprintf()函数里面,调用了WideCharToMultiByte()函数,就是通过当前的Locale将Unicode的字符转换成本地字符。在不使用setlocale()的时候,wprintf()会使用默认的“C”locale判断给定的宽字符是否<255,如果大于255就返回错误,而不会进行显示。这也就是在没有setlocale()的情况下wprintf((wchar_t*)paName)不能显示的真正原因。我觉得,如果wprintf()不进行这种判断而直接将字符串给Console的话,就能够正确显示了。但是,VC++中的wcout就可以在没有设置locale的情况下正确输出paName,可能就是象我说的一样。
测试环境VC8
相关文章推荐
- 解决使用VC运行时库函数wprintf和wcount显示中文不正确的问题
- mysql导入导出数据中文乱码解决方法小结(1、navicat导入问题已解决,创建连接后修改连接属性,选择高级->将使用Mysql字符集复选框去掉,下拉框选择GBK->导入sql文件OK;2、phpmyadmin显示乱码的问题也解决,两步:1.将sql文件以utf8的字符集编码另存,2.将文件中sql语句中的字段字符集编码改成utf8,导入OK)
- 使用xshell登录中文版CentOS时,在xshell下显示中文乱码,通过如下办法可以有效的解决乱码问题
- 解决Sublime Text 3不能正确显示中文的问题
- Python 3下使用Matplotlib工具画图,中文显示乱码的问题解决(修改配置文件)
- 如何解决Sublime Text 3不能正确显示中文的问题
- freetype使用日记 -- 解决宋体,楷体中文在某些字号下无法正常显示的问题
- 如何解决Sublime Text 3不能正确显示中文的问题
- 解决使用robot framework + selenium测试时,RIDE运行一次后不显示log的问题
- php使用fputcsv()函数csv文件读写数据的方法(解决中文乱码问题)
- 如何解决Sublime Text 3不能正确显示中文的问题
- [C] 跨平台使用TCHAR——让Linux等平台也支持tchar.h,解决跨平台时的格式控制字符问题,多国语言的同时显示(兼容vc/gcc/bcb,支持Windows/Linux/Mac)
- 【thrift】vc中使用thrift中文字符串乱码问题解决
- 如何解决 Sublime Text 3 不能正确显示中文的问题
- 解决 SQL 不能正确显示中文问题
- 在使用jscalendar时候,中文或者utf8不能正确使用的问题解决
- VC轻松解析XML文件--CMarkup使用方法(解决解析中文字符出现乱码问题)
- 如何解决Xshell使用时中文字体是躺倒显示的问题
- 解决使用CImage类的Draw函数在显示图片时引起的图像失真问题
- [Cocos2D-X]使用iconv解决VS上中文显示乱码的问题+android导入第三方库iconv