添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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.

What is the problem? You have already read everything from a file, why do you expect something remain to read? – Revolver_Ocelot Aug 6, 2016 at 19:56 you would need to rewind the file because you have consumed the stream with your call: insert ifs.seekg (0); between the calls. – Jean-François Fabre Aug 6, 2016 at 19:57 @puppydog Don't get discouraged. You'd likely be surprised how many engineers that routinely use C++ have no idea how things like rdbuf() actually work. Most don't really need to know for their day-to-day use, but once you start diving in it really is an interesting journey. Pat yourself on the back for taking time to swim out a little further from shore. – WhozCraig Aug 6, 2016 at 20:11 @puppydog According to the standard (eel.is/c++draft/ostream.inserters), operator<<(basic_streambuf<charT, traits>* sb) gets the characters from sb, which means it advances the seek position. I couldn't find any guarantee that get has to preserve the buffer for you to be able to seek back. – kfsone Aug 6, 2016 at 20:17

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

Conveying the same behavior using something very likely more familiar to the OP; well done, sir. – WhozCraig Aug 6, 2016 at 21:16

ifs.rdbuf() returns a pointer to the ifs's corresponding stream buffer object. Sending it to std::cout via << overload pulls information from the stream until the end of the buffer is reached (eof). Calling .rdbuf() again returns "nothing" because there's nothing to read at the end of the buffer. The buffer seek position be explicitly reset to zero by calling ifs.seekg (0);.

Note: Just invoking ifs.rdbuf() doesn't advance the seek position. It simply returns a pointer to the stream buffer object associated with the stream. It is what is done with that pointer afterward that matters. In this case, you're sending it to std::cout via an operator << overload, which will pull from it until eof, advancing the seekg position in the stream buffer while doing so. In short, it is sending the result of rdbuf() to a sink that is advancing its seek pos. Acquisition of the buffer object by rdbuf() is just the first step in that series of events. – WhozCraig Aug 6, 2016 at 21:02

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.