这两天碰到一个“诡异”的问题,写出来的程序,时而能正常运行,时而不能正常运行。代码如下:
这段代码的功能,就是将map中的键值遍历,并且对键值转换为utf8编码格式。每次编码转换完的键值,赋值给utf8这个字符串,并且将utf8更新到map中。
因为编码转换的函数,第三个参数采用引用传值,所以需要在传入之前,先将参数清空,也就是红色框起来的代码。
有意思的事情就是,程序编译后,发现utf8.clear()没有清空内容,因为实际看到的结果是,map中第一个键的键值,被更新到了后续每一个键的键值中去了。
于是怀疑光调用clear()函数不够,那就再加一个utf8=""。再次编译,运行,果然,utf8被清空了。完美。
但是回头再看clear()函数,描述如下:
说的很明白了,会清空内容,将长度调整为0。
究竟是什么原因呢?加一些打印信息看看,于是代码改为:
再次编译,测试,天杀的,竟然发现clear()是有效的,utf8明确被清空了。
多么诡异有意思的事情!难道是打印导致程序变正常了?尽管觉得很荒诞,还是试一试。那把cout屏蔽掉看看。
屏蔽掉后,如预料的一样,clear()确实是清了字符串了。
那既然cout压根没有起作用,那就删除呗。于是恢复到原来的样子,再次编译、运行。
结果是震惊的,utf8没有被清空。
到此时,脑海中复现了诡异论,心中骂起了CNM。
总归是有原因的....
再次加上cout,再次编译、运行,这次发现了一个有意思的事情:
1. clear()肯定是工作的。
2. 通篇看不到before字样
从第2点来看,cout<<"before clear "<<utf8<<endl这条语句就像被屏蔽掉一样。
如果cout<<"before clear "<<utf8<<endl会被屏蔽掉,那如果没有这条语句,被屏蔽掉的是不是就是utf8.clear()了?
这个就很容易验证了,把这句话删除,但是保留这一行,如下:
再次编译、运行,
事实证明,这次utf8被清空了。
看上去,如果没有空出这一行,utf8.clear()这条语句就像是紧跟着前一条语句,被屏蔽了。
这个时候,突然想到,因为这个代码,平时还需要在Linux下编译,所以文件格式UNIX格式的,也就是回车键为LF,非CRLF,是不是这个原因引起的呢?于是通过notepad++,将文件格式改为CRLF,同时将代码恢复成原始样子。
结果还就是对了,文件格式改为CRLF后,一切就正常了。
不过个人觉得这个解释还是很牵强,于是做了一个最简单的测试程序,如下所示:
无论文件格式是UNIX还是WINDOWS,teststr永远被清空。
所以,这件事情,究竟是什么引起的,在个人看来还是没有找到根本原因。看到本文的朋友们,如果有高见,希望点评。在下先谢过了!