一个由字符集引发的血案

      凡使用过VC编程的都知道,VC支持两种格式的编码,ASCII和Unicode,在字符串前面加L表示一个Unicode字符串,不加前缀则表示ASCII字符串,那么用_T()包含的字符串是什么编码呢,我想这里不用再解释了,用过VC的都知道。

       在VC编程里,如果要使用C函数输出一个字符串,该使用哪个函数呢?毫无疑问,要输出ASCII字符串使用printf,输出Unicode字符串使用wprintf,要输出与当前编译环境自适应的字符串使用_tprintf,确实我们就是这样使用的。如果不小心使用错误,没关系,VC会在编译的时候告诉我们,类型不匹配,这种情况下想出错都难。

       但是如果使用C++的<<操作符来输出应该怎么办呢?大家在使用C++的时候都喜欢用std::cout<<来输出,什么时候都用。输出整数,用std::cout;输出浮点数,用std::cout;输出字符串,用std::cout;输出自定义的类,重载<<操作符,然后用std::cout。你知道std::cout可以用于输出字符串,那你知不知道它只能用于ASCII的字符串?其实编译器也不知道,只有在程序运行的时候才知道,而且运行出错你也不一定知道是哪里出错了。

       好像有点偏题了,言归正传。既然有血案,那就来说说血案的事吧。

       某君使用VC编程,使用到了一个HANDLE,但是程序在运行的时候,一旦运行到使用这个HANDLE的地方就会崩溃。作为沙场老将,很快就找到了问题的原因,句柄获取失败了,三下五除二将其解决。

       当然,为了程序的健壮性,还得再做一点事情。将原来的代码改之:

HANDLE hHandle = 获取句柄;

std::cout << hHandle; /*调试时使用*/

if(hHandle) /*做该办的事情*/

else

std::cout << _T("出错信息");

       程序运行起来了,一个字,爽。

       但是好景不长,当环境变化后,运行又出错了。而且这一次,输出的句柄有效,但是该做的事没有做。没办法,只有调试。调试的时候句柄又是0啊,为什么输出的就不是0?百思不得其解,单步调试吧,每运行一步就查看一下输出信息。这不看不知道,一看吓一跳。本来前面输出的句柄是0,但是在输出出错信息的时候并没有按预期输出出错信息,而是输出了一个16进制数字00415800,与前面输出的0合在一起被误认为是有效的句柄了!

       到了这里,我想大家已经明白怎么回事了。当前的编译环境是Unicode编码,但是我们使用的是std::cout,却使用了_T()标记的字符串。std::cout只能用于ASCII编码的字符串,用来输出Unicode的字符串当然不行了。不用说,大家都知道要输出Unicode的字符串要使用std::wcout。但是如果要根据当前的编译环境变化怎么办呢。对于C++来说,VC并没有提供这样的转换,可以自己编写对应的宏来实现。

       好了,到此,此案已成功告破,希望大家能从中吸取经验教训,避免重蹈覆辙。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值