您的位置:首页 > 编程语言 > C语言/C++

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

2011-04-01 00:45 267 查看
原文地址: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
读入结果:"<<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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐