解决使用VC运行时库函数wprintf和wcount显示中文不正确的问题

昨天,我测试了c运行时库的locale方面的函数,发现了一些疑问,好像现在相通了。我的测试代码如下:
       {
char* paname = "测试中";
        wchar_t* pwname = l"测试中";
       
        printf(paname); //输出为:测试
        wprintf((wchar_t*)paname); //输出为:空
      
        printf((char*)pwname); //输出为:乱码
        wprintf(pwname); //输出为:空
    }
    如果将程序改写如下,则输出的结果就不一样了
    {
char* paname = "测试中";
        wchar_t* pwname = l"测试中";
       
       setlocale(lc_all, "chs");
      
        printf(paname); //输出为:测试
        wprintf((wchar_t*)paname); //输出为:空
       
        printf((char*)pwname); //输出为:乱码
        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,可能就是象我说的一样。 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值