cqdjyy01234
cqdjyy01234

Reputation: 1190

seekp before writing?

I want to read and write an binary file with a single file stream. The following code tries to read the first part of the file, and uses it to overwrite the second part of the file. But I find that I have to use "seekp(pos [,ios_base::begin]);" before writing. Additionally, "seekp" in fact doesn't change the position in my code, but it is necessary! Could any one give an explain? It should better be according to the c++ standard. Thanks very much!

#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;
 }

Comment: I find that if I use flib.seekp(some_number, ios_base::cur); with nonzero some_number, it works. And I use vs2012 express compiler, is it a bug?

Upvotes: 1

Views: 2499

Answers (1)

Michael Burr
Michael Burr

Reputation: 340208

File streams use a basic_filebuf<> for the stream buffer. The C++03 standard has this to say about class basic_filebuf<charT,traits>:

27.8.1.1 Class tempate basic_filebuf

The class basic_filebuf associates both the input sequence and the output sequence with a file.

The restrictions on reading and writing a sequence controlled by an object of class basic_filebuf are the same as for reading and writing with the Standard C library FILEs.

In particular: - If the file is not open for reading the input sequence cannot be read. - If the file is not open for writing the output sequence cannot be written. - A joint file position is maintained for both the input sequence and the output sequence.

Unfortunately it doesn't call out that when transitioning between reading and writing to a FILE object using the standard C library, you have to perform a file positioning call (or an fflush() when transitioning from write operations to read operations). See https://stackoverflow.com/a/14879076/12711.

Upvotes: 4

Related Questions