【发布时间】:2013-03-06 06:24:12
【问题描述】:
我想用一个文件流读写一个二进制文件。以下代码尝试读取文件的第一部分,并使用它来覆盖文件的第二部分。但我发现我必须使用“seekp(pos [,ios_base::begin]);”在写作之前。此外,“seekp”实际上并没有改变我代码中的位置,但它是必要的!任何人都可以解释一下吗?它应该更好地根据 c++ 标准。非常感谢!
#include <iostream>
#include <fstream>
using namespace std;
int main(){
fstream flib ("tmp.txt", ios::in | ios::out |ios::binary | ios::trunc);
if(!flib){
cerr << "file open failed!" << endl;
return 1;
}
int tmp;
for(int i = 0; i<2 ; i++){//write 2 numbers
flib.write((char*)&i, sizeof(tmp));
}
flib.seekg(0);
while(flib.read((char*)&tmp, sizeof(tmp))){//read file contents
cout <<tmp<<endl;
}
flib.clear();
flib.seekg(0);
flib.read((char*)&tmp, sizeof(tmp));
flib.seekp(sizeof(tmp)); //work
//flib.seekp(sizeof(tmp), ios_base::beg); //work
//flib.seekp(0, ios_base::cur); //not work
//flib.seekp(sizeof(tmp), ios_base::end); //not work
//flib.seekp(-sizeof(tmp), ios_base::end); //not work
flib.write((char*)&tmp, sizeof(tmp));
flib.clear();
flib.seekg(0);
while(flib.read((char*)&tmp, sizeof(tmp))){//read file contents
cout <<tmp<<endl;
}
return 0;
}
评论:我发现如果我使用 flib.seekp(some_number, ios_base::cur);使用非零 some_number,它可以工作。而且我用的是vs2012 express编译器,是不是bug?
【问题讨论】:
-
flib.seekp(0, ios_base::cur)究竟应该做什么?而flib.seekp(sizeof(tmp), ios_base::end);不应该工作,因为你试图寻找结束。 -
"flib.seekp(0, ios_base::cur)" 应该等价于 "flib.seekp(sizeof(tmp));",对吧? “flib.seekp(sizeof(tmp), ios_base::end);”可能是错的,但为什么不“flib.seekp(-sizeof(tmp), ios_base::end);”工作吗?
-
这是必要的,因为标准是这样说的。每当您从读取切换到写入或反之亦然(同一个文件)时,您都需要在两者之间进行查找或倒带。我相信这主要是为了给它一个刷新缓冲数据的机会,但我最近还没有仔细查看相关代码来确定。
-
flib.seekp(0, ios_base::cur)说“从当前位置寻找零字节”,所以它实际上应该什么都不做(所以它与flib.seekp(sizeof(tmp))不同,它说“移动到这个绝对位置”(就像flib.seekp(sizeof(tmp), ios_base::beg)))。至于flib.seekp(-sizeof(tmp), ios_base::end),我们得看看你是怎么称呼它的,因为它是Works For Me -
@user 是的,尺寸类型是无符号的。使用
-(int)sizeof(tmp)或-(long)sizeof(tmp)。