C++二进制文件读写问题

sosidami 2011-06-13 09:44:15
在遍历二进制文件的时候,总是在正确执行一定的二进制读取之后,v.fail()就会变成ture

void readType(std::ifstream &v, T *foo)
{
if(!v.good())
std::cout<< "Attention! Ifstream is not good"<< std::endl;
else
std::cout<< "Attention! Ifstream is good"<< std::endl;
//v.read((char *)foo, sizeof(T));
v.readsome((char *)foo, sizeof(T));
std::cout<<v.gcount()<<" bit has been read"<<endl;
if(v.eof()) std::cout<< "ERROR: EOF" <<std::endl;
if(v.bad()) std::cout<<"ERROR: badbit" <<std::endl;
if(v.fail()) std::cout<<"ERROR: failbit" <<std::endl;
}
for (int i = 0; i < NumDOFS; ++i)
{
char len;
readType(v, &len);
char * buffer_DOFlabel = new char[len];
v.read(buffer_DOFlabel, len);
DOFlabels.push_back(string(buffer_DOFlabel));
delete [] buffer_DOFlabel;
}


输出结果为:
Attention! Ifstream is good
1 bit has been read
DOFlabel 23's length: 23
DOFlabel 23's contents: khairi:RightFoot <t-Z>
Attention! Ifstream is good
0 bit has been read
DOFlabel 24's length: 26
DOFlabel 24's contents: 屯屯屯屯屯屯屯屯屯屯屯屯屯铪铪铪铪铪
Attention! Ifstream is not good
0 bit has been read

第23此执行能够正确执行,得到的内容是khairi:RightFoot <t-Z>,第24次执行就出现错误。请问这个是由什么引起的?有什么调试方法吗?
...全文
253 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
sosidami 2011-06-16
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 luciferisnotsatan 的回复:]

引用 10 楼 luciferisnotsatan 的回复:

C/C++ code

void readType(std::ifstream &amp;v, T *foo)
{


模版不是这么写的吧,开头那段呢?
暂且不管模版这部分

C/C++ code
char len;
readType(v, &amp;len);


v.readsom……
[/Quote]

我获取的len的时候,在len中已经考虑到了'\0'的问题,我的二进制文件都能够保证在[len-1]位是0x00,所以开len长度的空间是正确的。

目前存在的问题是当我的取下一段len是0x1A,即26的时候,我的tellg()会自动向后偏移512个字节。这个问题没有解决。现在只能通过强制seekg()来解决。

for (int i = 0; i < NumDOFS; ++i) {
unsigned char len=0x1A;

readType(v, &len);

if (VDEBUG) cout << "DOFlabel " << i << "'s length: " << (int)(len) << endl;

char * buffer_DOFlabel = new char[(int)len];

if (VDEBUG) cout<<"buffer before "<<v.tellg()<<endl;

int prepos=v.tellg();

if (VDEBUG) cout<<"The len is "<<(int)len <<endl;

v.read(buffer_DOFlabel, (int)len);

if (VDEBUG) cout<<"buffer after "<<v.tellg()<<endl;

DOFlabels.push_back(string(buffer_DOFlabel));
//v.seekg(len, std::ios_base::cur);
v.seekg(prepos + (int)len,std::ios_base::beg);

if (VDEBUG) cout<<"buffer after t "<<v.tellg()<<endl;

delete [] buffer_DOFlabel;
if (VDEBUG) cout << "DOFlabel " << i << "'s contents: " << DOFlabels[i] << endl;
}
sosidami 2011-06-16
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 qq120848369 的回复:]

C/C++ code
读文件要遵循如下格式:

read();

while(!feof())
{
cout<<buffer<<endl;
read();
}
[/Quote]

这个文件数据段很多,我需要使用不同的数据结构来分别读取不同的数据段,整个程序的框架可以保证是这个样子的
sosidami 2011-06-16
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 shi3590 的回复:]

char * buffer_DOFlabel = new char[len+1];
[/Quote]

不是这个问题,我解释的可能不清楚,在len中已经考虑到了'\0'的问题,我的二进制文件都能够保证在[len-1]位是0x00,所以开len长度的空间是正确的。
目前存在的问题是当我的取下一段len是0x1A,即26的时候,我的tellg()会自动向后偏移512个字节。这个问题没有解决。现在只能通过强制其seekg()来解决
luciferisnotsatan 2011-06-15
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 luciferisnotsatan 的回复:]

C/C++ code

void readType(std::ifstream &v, T *foo)
{


模版不是这么写的吧,开头那段呢?
暂且不管模版这部分

C/C++ code
char len;
readType(v, &len);


v.readsome((char *)foo, sizeof……
[/Quote]
重新看了下,看懂你的意思了。

read这个函数是不会加字符串结束符('\0'),自己加上。同样的,你获取的len长度,是含有最后的结束符的长度吗?不是的话,分配时加上1
luciferisnotsatan 2011-06-15
  • 打赏
  • 举报
回复

void readType(std::ifstream &v, T *foo)
{

模版不是这么写的吧,开头那段呢?
暂且不管模版这部分

    char len;                    
readType(v, &len);


v.readsome((char *)foo, sizeof(T));

这个sizeof不就1个字节(char的大小)?foo不是len么,你这有把它转成char *,当buf用?

请把代码先写写对。

streamsize readsome(
char_type *_Str,
streamsize _Count
);



Parameters
_Str
The array in which to read the characters.

_Count
The number of characters to read.

Return Value
The count of items in the buffer.

Remarks
The unformatted input function extracts up to count elements and stores them in the array beginning at _Str. If good is false, the function calls setstate(failbit). Otherwise, it assigns the value of rdbuf->in_avail to N. If N < 0, the function calls setstate(eofbit). Otherwise, it replaces the value stored in N with the smaller of _Count and N, and then calls read(_Str, N). In any case, the function returns gcount.
qq120848369 2011-06-15
  • 打赏
  • 举报
回复
读文件要遵循如下格式:

read();

while(!feof())
{
cout<<buffer<<endl;
read();
}
qq120848369 2011-06-15
  • 打赏
  • 举报
回复
木有看懂额...
shi3590 2011-06-15
  • 打赏
  • 举报
回复
char * buffer_DOFlabel = new char[len+1];
sosidami 2011-06-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 wcyoot 的回复:]

俩地方都发了 a

readsome()造成的。
看MSDN解释:Read from buffer only.
Remarks
The unformatted input function extracts up to count elements and stores them in the array beginning at _Str. If good is false, t……
[/Quote]

把readsome改成read之后,仍然会存在错误。只不过把能够检查到流的错误延迟了一步。问题还是没有解决。
sosidami 2011-06-15
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 relaxisland 的回复:]

没大看懂什么意思?

根据读出来的char大小,来再读相应字节的数据?

会不会参数不对?或者数据结束?

if(!v.good())
std::cout<< "Attention! Ifstream is not good"<< std::endl;
else
std::cout<< "Attention! Ifstream is ……
[/Quote]

v.good()就证明了你的流是有效的。
是根据读出来的char类型一个字节的大小来读取下面的。这个格式是没有问题的。但不清楚为什么会出错
sosidami 2011-06-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 dizuo 的回复:]

遇到了结束符 -1了吧。。。
[/Quote]

不是这个问题,每次当要读取的位是1A的时候,会出错
方寸之间 2011-06-14
  • 打赏
  • 举报
回复
俩地方都发了 a

readsome()造成的。
看MSDN解释:Read from buffer only. 
Remarks
The unformatted input function extracts up to count elements and stores them in the array beginning at _Str. If good is false, the function calls setstate(failbit). Otherwise, it assigns the value of rdbuf->in_avail to N. If N < 0, the function calls setstate(eofbit). Otherwise, it replaces the value stored in N with the smaller of _Count and N, and then calls read(_Str, N). In any case, the function returns gcount. 

如果N == 0时(即buffer为NULL),就会造成了上面的结果
relaxisland 2011-06-13
  • 打赏
  • 举报
回复
没大看懂什么意思?

根据读出来的char大小,来再读相应字节的数据?

会不会参数不对?或者数据结束?

if(!v.good())
std::cout<< "Attention! Ifstream is not good"<< std::endl;
else
std::cout<< "Attention! Ifstream is good"<< std::endl; //这下面也可以判断一下是bad还是fail吧。
//v.read((char *)foo, sizeof(T));
v.readsome((char *)foo, sizeof(T));
ryfdizuo 2011-06-13
  • 打赏
  • 举报
回复
遇到了结束符 -1了吧。。。

64,645

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧