2013-03-06 51 views
0

我想用一个文件流读取和写入二进制文件。以下代码尝试读取文件的第一部分,并使用它覆盖文件的第二部分。但是我发现我必须使用“seekp(pos [,ios_base :: begin]);”写之前。另外,“seekp”实际上不会改变我的代码中的位置,但它是必要的!任何人都可以解释吗?最好根据C++标准。非常感谢!seekp在写之前?

#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编译器,它是一个错误吗?

+0

“flib.seekp(0,ios_base :: cur)'应该做什么? 'flib.seekp(sizeof(tmp),ios_base :: end);'不应该工作,因为你试图寻找*超过结尾*。 – Cornstalks 2013-03-06 06:31:47

+0

“flib.seekp(0,ios_base :: cur)”应该等同于“flib.seekp(sizeof(tmp));”,对吧? “flib.seekp(sizeof(tmp),ios_base :: end);”可能是错误的,但为什么不“flib.seekp(-sizeof(tmp),ios_base :: end);”工作? – cqdjyy01234 2013-03-06 06:35:46

+4

这是必要的,因为标准是这样说的。任何时候你从阅读转向写作或反过来(同一个文件),你需要在两者之间进行寻找或倒带。我相信主要是给它一个冲洗缓冲数据的机会,但最近我还没有仔细查看相关代码,以确保。 – 2013-03-06 06:38:26

回答

4

文件流使用basic_filebuf<>作为流缓冲区。在C++ 03标准是这样说的约class basic_filebuf<charT,traits>

27.8.1.1类tempate basic_filebuf

类basic_filebuf联营两个输入 序列和与文件输出序列。

上读取和写入由类basic_filebuf的 对象控制的序列的限制是一样的 读数并与标准C库FILE在写。

特别是: - 如果文件没有打开读取,输入序列无法读取。 - 如果文件未写入,输出序列不能写入。 - 为输入序列和输出序列都保留一个联合文件位置。

遗憾的是它不叫唤,阅读之间的转换,并使用标准C库写入FILE对象时,你必须执行一个文件定位呼叫(或fflush()从写入操作转变到读操作时)。见https://stackoverflow.com/a/14879076/12711

相关问题