I have this std::stringstream
object whose contents I have to read (only) twice. For this I thought I could use its seekg
member function to repeat the reading. But I can't make it work. Here's a MWE that reproduces the issues I'm having (adapted from the example in the docs).
#include <iostream>
#include <string>
#include <sstream>
int main()
{
const char *str = "Hello, world";
std::stringstream ss(str);
std::string word1 = "asdf";
std::string word2 = "qwer";
std::string word3 = "zxcv";
std::string word4 = "yuio";
ss >> word1;
ss.seekg(0); // rewind
ss >> word2;
while (ss >> word3) { }
ss.seekg(0); // rewind
ss >> word4;
std::cout << "word1 = " << word1 << '\n'
<< "word2 = " << word2 << '\n'
<< "word3 = " << word3 << '\n'
<< "word4 = " << word4 << '\n';
}
I expect the contents to be:
word1 = Hello,
word2 = Hello,
word3 = world
word4 = Hello,
since the call ss.seekg(0)
after the while loop should put ss
at the beginning of its contents. Why do I not get the expected output, but rather this?
word1 = Hello,
word2 = Hello,
word3 = world
word4 = yuio
This means that word4
is never updated, thus the statement ss >> word4
has no effect. But in this case, then the ss.seekg(0)
does not have any effect either.
Is the while loop causing the ss
object to fail to "rewind"? Perhaps the ss
tried to read too much and now is in an error state (I have no idea).
How can I fix this? That is, how can I make the statement ss >> word4
read Hello,
?
I'm using g (Ubuntu 11.1.0-1ubuntu1~20.04) 11.1.0
on C 17.
CodePudding user response:
seekg
first constructs and checks the sentry object (used by cppstreams to represent any stream failure), if that sentry object represents any failure then the function just returns without doing anything.
After the while loop, ss
's failbit
and eofbit
will be set. The call to seekg will behave as described before (won't do anything).
For seekg
to take any affect, you will have to clear the failure bits by calling ss.clear()
before calling seekg
itself after the while loop. Then, the sentry object won't represent any failure and seekg
will behave as expected.
Relevant links:
https://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt2