Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

seekp and seekg don't work with fstream

Tags:

c++

fstream

I have a strange behaviour in my c++ program running on Debian x64 PC.

I cannot manage to first read file, then write another value and then read these values. I've read a lot of info, including questions on stackoverflow, found out (also via experiments) that I need to change both seekp and seekg and I do so. Everything works... until I read something from a stream. After a read operation if I seek on begining of the file and then call tellg(), tellp(), they both return '-1'.

Test code:

void testFstreamSeekp() {
    fstream in("file", ios::in | ios::out);

    cout << "g: " << in.tellg() << endl;
    cout << "p: " << in.tellp() << endl;

    in.seekp(0, ios_base::end);

    cout << "endp g: " << in.tellg() << endl;
    cout << "endp p: " << in.tellp() << endl;

    in.seekp(0, ios_base::end);
    in.seekg(0, ios_base::end);

    cout << "end g: " << in.tellg() << endl;
    cout << "end p: " << in.tellp() << endl;

    in.seekp(0, ios_base::beg);
    in.seekg(0, ios_base::beg);

    cout << "beg g: " << in.tellg() << endl;
    cout << "beg p: " << in.tellp() << endl;

        // Everything is fine until here (that is tellp() == 0, tellg() == 0)
    int a, b;
    in >> a >> b;
    cout << "a: " << a << endl << "b: " << b << endl;

        // tellg() == -1, tellp() == -1 ?????????!!!!!!!!!!
    cout << "read g: " << in.tellg() << endl;
    cout << "read p: " << in.tellp() << endl;

    in.seekp(0, ios_base::beg);
    in.seekg(0, ios_base::beg);

        // tellg() == -1, tellp() == -1 ?????????!!!!!!!!!!
    cout << "beg g: " << in.tellg() << endl;
    cout << "beg p: " << in.tellp() << endl;
}

Can somebody tell me what happens and what can I do to solve the problem?

like image 548
Arks Avatar asked Aug 12 '13 12:08

Arks


1 Answers

For fstream (std::basic_filebuf), the single file position is moved by both seekp() and seekg()

Keeping track of put and get positions independently not possible.

The class template std::basic_filebuf holds a single file position

§ 27.9.1.1

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

  2. 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.

  3. 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.
like image 102
P0W Avatar answered Sep 28 '22 03:09

P0W