记c++binary模式读文件时遇到的bug

bug起源

最近在做解析二进制文件的工作,我的做法是写一个继承自ifstream的类然后封装一些函数以便于读取,譬如readUint32(), readHexString()等等。然后发现一个很隐蔽的bug........

bug简述

在读取一个数据时,该数据以00H结尾,我调用自己的函数返回一个string,请看下面简化的代码段:

include

include

using namespace std;
int main()
{
string str{ "test.aaa..ddd.bbb" };
str.push_back(0x00);
cout << str < }

此时的输出会是什么呢?


image.png

加和不加没区别?非也!你去掉代码里的 endl就会发现尾部还有一个“空格”。于是乎,

if (str == "test.aaa..ddd.bbb")
>_<;

是不会被执行的。。

不止如此

00H这个字符的特殊性在于, 它会使 如下代码

if (str == "test.aaa..ddd.bbb ") // 多一个空格
_;
if (str == "test.aaa..ddd.bbb\0")
(;
// 以及
if (str + " " == "test.aaa..ddd.bbb")
QAQ;

同样不被执行。

原因

上面提到“空格”一词时,加上了引号,因为它并非我们常说的空格。ascii码表里00H 和32H的字符形式都是空白,而32H则是我们键盘上敲空格键敲出来的。即,执行如下代码:

cout << (int)(' ');

则得到 32。

最后一个疑惑是,ascii码表上 00H也可以用转义字符代替,那为何

str == "test.aaa..ddd.bbb\0"

的值是0,然而,如下代码段

string str{ "test.aaa..ddd.bbb" };
string yastr{ str };
str.push_back(0x00);
yastr.push_back('\0');

却会使 yastr 和str相等呢?

yastr == str ----> 1

我的实验环境是vs2015,这样的结果可能是取决于编译器(string == 操作的实现),也可能是c++认为字符字面量后面加\0没有实际的意义,后者是比较显然的。

总体来说今天的bug之旅以及反思都是愉快的。虽然有收获……但是……下次别再让我碰到你!

你可能感兴趣的:(记c++binary模式读文件时遇到的bug)