我想用一个文件流读写一个二进制文件。下面的代码尝试读取文件的第一部分,并使用它覆盖文件的第二部分。但是我发现我必须使用“ 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

10-07 23:33