美文网首页
记c++binary模式读文件时遇到的bug

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

作者: 懒懒的我 | 来源:发表于2015-12-02 00:32 被阅读0次

    bug起源

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

    bug简述

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

    include <iostream>

    include <string>

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

    此时的输出会是什么呢?


    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

          本文链接:https://www.haomeiwen.com/subject/pngjhttx.html