我想用一个文件流读写一个二进制文件。下面的代码尝试读取文件的第一部分,并使用它覆盖文件的第二部分。但是我发现我必须使用“ 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编译器,这是一个错误吗?
最佳答案
文件流使用basic_filebuf<>
作为流缓冲区。 C ++ 03标准关于class basic_filebuf<charT,traits>
的说法是这样的:
27.8.1.1类模板tempate basic_filebuf
class basic_filebuf类将两个输入关联
序列和带有文件的输出序列。
对读写控制的限制
class basic_filebuf的对象与for相同
使用标准C库FILE
进行读写。
尤其是:
-如果未打开文件进行读取,则无法读取输入序列。
-如果未打开要写入的文件,则无法写入输出序列。
-输入序列和输出序列都保持联合文件位置。
不幸的是,它并没有指出在使用标准C库在对FILE
对象的读写之间进行转换时,您必须执行文件定位调用(或在从写入操作向读取操作过渡时使用fflush()
)。请参见https://stackoverflow.com/a/14879076/12711。