Click here to Skip to main content
15,904,935 members
Please Sign up or sign in to vote.
4.50/5 (2 votes)
See more:
Im a little confused about the following issue. I'm using a fstream with a binary file. Initially what i wanted to do is to read a value from the file which was just written to it. So i'll need a in|out mode.

What i thought so far is that the get pointer of the stream is used and advanced when performing a read() and accordingly the put pointer when using write() (i only worked with ifstream and ofstream before).

But as the following test shows, it seems that they are in fact allways pointing to the same position. So both the pointers are advanced when doing a read(), write or seek() operation.

C#
std::fstream inOutStream("tmp_file", std::ios::out | std::ios::in | std::ios::binary | std::ios::ate);
    if(inOutStream)
    {
        double tmp = 123.123123;
        std::cout << "Put pointer position after opening stream: " << inOutStream.tellp() << std::endl;
        std::cout << "Get pointer position after opening stream: " << inOutStream.tellg() << std::endl;

        inOutStream.write((char*) &tmp, sizeof(double));
        inOutStream.flush();

        std::cout << "Put pointer position after writing to stream: " << inOutStream.tellp() << std::endl;
        std::cout << "Get pointer position after writing to stream: " << inOutStream.tellg() << std::endl;

        inOutStream.seekg(std::ios_base::beg);

        std::cout << "Put pointer position after moving get pointer to begin: " << inOutStream.tellp() << std::endl;
        std::cout << "Get pointer position after moving get pointer to begin: " << inOutStream.tellg() << std::endl;

        double tmp2 = 0.0;
        inOutStream.read((char*)&tmp2, sizeof(double));

        std::cout << "Put pointer position after reading from stream: " << inOutStream.tellp() << std::endl;
        std::cout << "Get pointer position after reading from stream: " << inOutStream.tellg() << std::endl;
}


And the output is:
CSS
Put pointer position after opening stream: 0
Get pointer position after opening stream: 0
Put pointer position after writing to stream: 8
Get pointer position after writing to stream: 8
Put pointer position after moving get pointer to begin: 0
Get pointer position after moving get pointer to begin: 0
Put pointer position after reading from stream: 8
Get pointer position after reading from stream: 8


Wasn't my assumption something one would expect and wouldn't it be more convenient if the pointers where to point at different positions?
Posted
Updated 13-Apr-11 21:40pm
v2
Comments
Bharat Kumar Arya 14-Apr-11 5:33am    
Interesting... looking fwd for an answer :)

1 solution

The pointers are not different, and the internal call to seekpos(pos_type __pos, ios_base::openmode) is ignoring the openmode parameter. The implementation for Microsoft VC and gcc both ignore it. I found a comment in the fstream source for gcc
C++
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 171. Strange seekpos() semantics due to joint position
// According to the resolution of DR 171, seekpos should ignore the last
// argument (of type openmode).
which lead me to the Defect Report, DR 171, see pdf here[^] and scoll down to (or seach for) 171 on page 35.

In short it suggests that implementations should look for the openmode sent to the call to open() instead of the call to seekpos(). Hence the somewhat unintuitive behavior.

Edit: missed a 'not'

According to the basic_filebuf specification: "A joint file position is maintained for both the input sequence and the output sequence"
 
Share this answer
 
v3
Comments
Legor 14-Apr-11 7:39am    
Thanks a lot for digging that up! I think that explains the problem allthough i have to admit i didn't get this in detail. So does this mean i'll have to manage the file positions myself ( e.g. with temporary variables) lets say for the simple task of reading a value from a file just written to it?
Niklas L 14-Apr-11 15:17pm    
Unless you want to write your own filebuf implementation, I'd say yes.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900