Pre-history: I'm trying to ensure that some function foo(std::stringstream&)
consumes all data from the stream.
Answers to a previous question suggest that using stringstream::str()
is the right way of getting content of a stringstream. I've also seen it being used to convert arbitrary type to string
like this:
std::stringstream sstr;
sstr << 10;
assert(sstr.str() == std::string("10")); // Conversion to std::string for clarity.
However, the notion of "content" is somewhat vague. For example, consider the following snippet:
#include <assert.h>
#include <sstream>
#include <iostream>
int main() {
std::stringstream s;
s << "10 20";
int x;
s >> x;
std::cout << s.str() << "\n";
return 0;
}
On Ideone (as well as on my system) this snippet prints 10 20
, meaning that reading from stringstream
does not modify what str()
returns. So, my assumption is that that str()
returns some internal buffer and it's up to stringstream
(or, probably, its internal rdbuf
, which is stringbuf
by default) to handle "current position in that buffer". It's a known thing.
Looking at stringbuf::overflow()
function (which re-allocates the buffer if there is not enough space), I can see that:
this may modify the pointers to both the input and output controlled sequences (up to all six of eback, gptr, egptr, pbase, pptr, epptr).
So, basically, there is no theoretical guarantee that writing to stringstream
won't allocate a bigger buffer. Therefore, even using stringstream::str()
for converting int
to string
is flawed: assert(sstr.str() == std::string("10"))
from my first snippet can fail, because internal buffer is not guaranteed to be precisely of the necessary size.
Question is: what is the correct way of getting the "content" of stringstream
, where "content" is defined as "all characters which could be consumed from the steream"?
Of course, one can read char-by-char, but I hope for a less verbose solution. I'm interested in the case where nothing is read from stringstream
(my first snippet) as I never saw it fail.