读取二进制文件
我必须从二进制文件读取数据。 该二进制数据格式为: 0x00 0x00 0x01 - 是分隔符 在此分隔符之后是原始数据字节数组。 所以,总而言之,我的二进制文件如下所示:
0x00 0x00 0x01(这里是原始数据字节) 0x00 0x00 0x01(这是另一个块 原始数据字节)0x00 0x00 0x01 ....
所以我写了这样的代码来解析我的文件(我对C不太熟悉)
ifstream inp("myfile.bin",ios::binary);
char b1, b2, b3;
while (!inp.eof())
{
inp.read(&b1,sizeof(b1));
inp.read(&b2,sizeof(b2));
inp.read(&b3,sizeof(b3));
//finding first delimiter (data starts from delimiter)
while (!((0==b1)&&(0==b2)&&(1==b3)))
{
b1=b2;
b2=b3;
if (inp.eof())
break;
inp.read(&b3,sizeof(b3));
}
if (inp.eof())
break;
char* raw=new char[65535];
int rawSize=0;
inp.read(&b1,sizeof(b1));
inp.read(&b2,sizeof(b2));
inp.read(&b3,sizeof(b3));
raw[rawSize++]=b1;
raw[rawSize++]=b2;
if (inp.eof())
break;
//reading raw data until delimiter is found
while (!((0==b1)&&(0==b2)&&(1==b3)))
{
raw[rawSize++]=b3;
b1=b2;
b2=b3;
if (inp.eof())
break;
inp.read(&b3,sizeof(b3));
}
rawSize-=2; //because of two bytes of delimiter (0x00 0x00) would be added to raw
//Do something with raw data
if (inp.eof())
break;
inp.putback(1);
inp.putback(0);
inp.putback(0);
delete []raw;
}
但有时这个代码会陷入无限循环。 你能给我一些建议吗? 谢谢
I've to read data from binary file.
This binary data format is:
0x00 0x00 0x01 - is delimiter
after this delimiter there is raw data byte array.
So, to sum up, my binary file looks like:
0x00 0x00 0x01 (here is raw data byte)
0x00 0x00 0x01 (here is another block
of raw data bytes) 0x00 0x00 0x01 ....
So i've wrote such code to parse my file (I'm not very familiar with C)
ifstream inp("myfile.bin",ios::binary);
char b1, b2, b3;
while (!inp.eof())
{
inp.read(&b1,sizeof(b1));
inp.read(&b2,sizeof(b2));
inp.read(&b3,sizeof(b3));
//finding first delimiter (data starts from delimiter)
while (!((0==b1)&&(0==b2)&&(1==b3)))
{
b1=b2;
b2=b3;
if (inp.eof())
break;
inp.read(&b3,sizeof(b3));
}
if (inp.eof())
break;
char* raw=new char[65535];
int rawSize=0;
inp.read(&b1,sizeof(b1));
inp.read(&b2,sizeof(b2));
inp.read(&b3,sizeof(b3));
raw[rawSize++]=b1;
raw[rawSize++]=b2;
if (inp.eof())
break;
//reading raw data until delimiter is found
while (!((0==b1)&&(0==b2)&&(1==b3)))
{
raw[rawSize++]=b3;
b1=b2;
b2=b3;
if (inp.eof())
break;
inp.read(&b3,sizeof(b3));
}
rawSize-=2; //because of two bytes of delimiter (0x00 0x00) would be added to raw
//Do something with raw data
if (inp.eof())
break;
inp.putback(1);
inp.putback(0);
inp.putback(0);
delete []raw;
}
But sometimes this code falls into infinite loop.
Could you advice me something?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为问题在于
putback
失败。据我记得,putback
保证只能工作一次;如果内部读取缓冲区对齐(也就是说,很少;看起来像您的情况),第二次调用将失败。要修复此问题,请删除
putback
。首先,将注释为“查找第一个分隔符”的循环移出外部while
循环:注释表明此代码应该只运行一次。完成后,请注意,在外部while
循环的开始处,刚刚找到了序列0x00 0x00 0x01
,因此代码不必使用putback
并再次查找。I think the problem there is that
putback
fails. As far as i recall,putback
is guaranteed to work only once; second invocation will fail if the internal read buffer is aligned (that is, very rarely; seems like your situation).To fix, get rid of
putback
. First of all, move the loop commented as "finding first delimiter" out of the outerwhile
loop: the comment suggests that this code should only run once. After you do it, pay attention that at the beginning of the outerwhile
loop, the sequence0x00 0x00 0x01
has just been found, so the code doesn't have to useputback
and look for it again.您使用的
feof()
是错误的,它仅在尝试读取但失败后才有效。你怎么知道你的神奇字节序列 0 0 1 没有出现在数据中?如果数据只是一个“二进制数组”,听起来并没有提供太多保证...
You're using
feof()
wrong, it's only valid after a read has been attempted and failed.How do you know that your magic byte sequence 0 0 1 doesn't appear inside the data? If the data is just a "binary array" that doesn't sound like it provides much of a guarantee ...