puppydog puppydog - 3 months ago 13
C++ Question

Weird behavior with ifstreams and rdbuf()

I've noticed that using

.rdbuf()
on an
ifstream
seems to change it somehow. The following code should show the problem.

#include <fstream>
#include <iostream>

using namespace std;

int main(int argc, const char * argv[]) {
ifstream ifs("Sample.csv");
cout << "Reading buffer: " << endl;
cout << ifs.rdbuf(); // Outputs buffer as expected
cout << "Reading buffer again: " << endl;
cout << ifs.rdbuf(); // Returns nothing

return 0;
}


The reason this is bothering me is that I'm currently trying to copy the contents of one text file into another using
ofstream ofs; ofs << ifs.rdbuf()
. This works fine but makes reading from
ifs
using
getline(ifs, str)
fail, effectively "breaking" the stream.

Answer

This isn't particularly "weird"; it's the same stream behaviour you see every day. rdbuf isn't like std::stringstream::str() and it isn't magic — it's a pointer to the buffer, that your cout is then reading from just as you would read from the original stream yourself:

std::stringstream ss("1");
int x;
if (ss >> x)
   cout << x;
if (ss >> x)   // doesn't work a second time; "1" is already extracted
   cout << x;

As your stream is a file stream, you can seek it back to the beginning to start from scratch (which will inherently do the same to its underlying buffer).

Comments