Does std::stringstream has two buffers and hence two markers?

Viewed 82

On C++ primer chapter 17; I/O streams; it is said that an object of type std::iostream or a derived type like std::fstream, std::stringstream support both reading and writing. Also these types have only one Marker and a single Buffer:

The fstream and stringstream types can read and write the same stream. In these types there is a single buffer that holds data to be read and written and a single marker denoting the current position in the buffer. The library maps both the g and p positions to this single marker.

So to understand more I've done this program:

int main(){


    std::fstream fio("data.txt");
    std::cout << fio.tellg() << '\t' << fio.tellp() << '\n';
    fio.seekg(0, std::ios::end);
    std::cout << fio.tellg() << '\t' << fio.tellp() << '\n';

    std::stringstream ss("abcd\nefg\nhi\nj");
    std::cout << ss.tellg() << '\t' << ss.tellp() << '\n';
    ss.seekg(0, std::ios::end);
    std::cout << ss.tellg() << '\t' << ss.tellp() << '\n';

}

The output:

 0      0
 14     14
 0      0
 13     0 
  • As you can see when using std::fstream if I move the read marker using seekg() then the tellg and tellp return the same value. Which is so logical.

  • However when moving the read marker for std::stringstream, tellg and tellp return different value so the write marker hasn't been moved?

  • Does this mean std::stringstream has two buffers and two markers? Thanks

1 Answers

Yes, the book is wrong.

It is std::basic_filebuf which synchronizes read and write positions, and,

the class template basic_fstream implements high-level input/output operations on file based streams. It interfaces a file-based streambuffer (std::basic_filebuf) with the high-level interface of (std::basic_iostream).

The base class however, std::basic_streambuf, does maintain separate input and output buffers. Note that

the I/O stream objects std::basic_istream and std::basic_ostream, as well as all objects derived from them (std::ofstream, std::stringstream, etc), are implemented entirely in terms of std::basic_streambuf.

Related