关于C++读入二进制文件要注意的问题(转自百度空间)

原文地址:
http://apps.hi.baidu.com/share/detail/24190387

 

刚好遇见这个问题,记录下来备用!

关于C++读入二进制文件要注意的问题

  今天帮一个网友调程序,其中涉及读入二进制文件(关于什么是二进制文件和文本文件,我就不在这里赘述了,百度一搜就知道了),很久没有用C++对文件进行操作了,有点手生,怎么调都运行不出想要的结果,一点一点的排除,最终把问题锁定在文件读入这一部分。

 

  后来我把程序改成了fopen和fread这种C语言的函数,程序运行就正常了。难道是C++对二进制文件的读入存在bug?当然不是,C++ 这个发展了几十年、成千上万的程序员用的东西当然不会有这种低级错误,肯定是程序员自身的问题。后来我把程序改成了in.read(...)这种方式读入 数据,也成功了,这就说明不能用in>>ch[i]这种方式读入文件。但是为什么不能这么读呢?我写了程序研究了一下。

        #include <iostream>
        #include <fstream>
        #include <iomanip>
        using namespace std;

        void init_array(char* ch, int length) //将数组全部置0
        {
            memset(ch, 0, length);
        }

        void show_array(char* ch, int length)
        {
            for(int i = 0; i < length; ++i)
            {
                cout<<setw(4)<<hex<<(int)ch[i];
            }
            cout<<endl<<endl;
        }

        int main()
        {
            char out[10]={0x31, 0x32, 0x0A/*换行*/, 0x0D/*回车*/,
                0x20/*空格*/, 0x48, 0x3C, 0x09/*制表*/, 0x45, 0x55};
            char in[10];
           
            cout<<"二进制文件里的内容:"<<endl;
            show_array(out, 10);
            ofstream wf;
            wf.open("text.dat", ios::out | ios::binary);
            wf.write(out, 10);
            wf.close();

            init_array(in, 10);
            ifstream rf1;
            rf1.open("text.dat", ios::in | ios::binary);
            rf1.read(in, 10);
            rf1.close();
            cout<<"ifstream.read() 读入结果:"<<endl;
            show_array(in, 10);

            init_array(in, 10);
            ifstream rf2;
            rf2.open("text.dat", ios::in | ios::binary);
            int n = 0;
            while(rf2 >> in[n++]);
            rf2.close();
            cout<<"ifstream>>in[n] 读入结果:"<<endl;
            show_array(in, 10);
           
            system("pause");
            return 0;
        }

运行结果如图所示:

  从运行结果就可以看出,用“>>”的这种方式没有读入0x0A、0x0D、 0x20、0x09这几个字符,而这几个字符正好是换行、回车、空格、制表符,也就是通常所说的空白字符。众所周知,cin>>默认是不读入 空白字符的,其实文件的“>>”读入方式也是如此,如果二进制文件的哪个字节恰好与空白字符的ASCII码相同,就会被舍弃,这一点是不期望 的,当文件较大时,遇到这种情况的概率是很高的。所以用“>>”读入二进制文件,读入的字节数会小于文件本身的字节数。

  综上所述,用C++读入二进制文件时,不能用“>>”这种方式,要使用read()函数。

  原始程序是这样的:
  ifstream in("...", ios::binary);
  while(in >> ch[i++]); //ch是字符数组,i初值为0

posted @ 2011-04-01 00:45  向ET同志学习  阅读(928)  评论(0编辑  收藏  举报