C++ - Does resetting stringstream not reset the get position or clear flags?
As @Someprogrammerdude suggests: simply move your istringstream
inside your while
loop (which you can change to a for
loop to keep in
in the loop as well):
for (string in; cin >> in;)
{
istringstream word(in);
int number;
if (!(word >> number))
{
cerr << "Failed to read int" << endl;
return 1;
}
cout << in << ' ' << number << endl;
}
that way it's re-created each loop.
While you're at it, move number
in there too (unless you use it outside the loop, of course).
If you look at the state of the stream, this should be a bit clearer.
int main()
{
std::vector<std::string> words = { "10", "55", "65" };
std::istringstream word;
for (const auto &in : words)
{
word.str(in);
std::cout << "stream state:"
<< (word.rdstate() & std::ios::badbit ? " bad" : "")
<< (word.rdstate() & std::ios::failbit ? " fail" : "")
<< (word.rdstate() & std::ios::eofbit ? " eof" : "")
<< std::endl;
int number;
word >> number;
if (word.fail()) {
std::cerr << "Failed to read int" << std::endl;
return 1;
}
std::cout << in << ' ' << number << std::endl;
std::cout << "stream state:"
<< (word.rdstate() & std::ios::badbit ? " bad" : "")
<< (word.rdstate() & std::ios::failbit ? " fail" : "")
<< (word.rdstate() & std::ios::eofbit ? " eof" : "")
<< std::endl;
}
}
Which will result in:
stream state: 10 10 stream state: eof stream state: eof Failed to read int
So initially none of the flags are set, but reading the number reaches the end of the stream, setting eofbit
. std::istringstream::str
is defined as if to call rdbuf()->str(new_str)
. That says nothing about clearing flags.
Calling clear()
will of course clear the eofbit
, but so does calling seekg
in C++11 or newer. "
Before doing anything else, seekg clears eofbit. (since C++11)".
Note that if you had say "10 20", that it will just discard the " 20", and not detect an error.
stream state: 10 20 10 stream state: stream state: 55 55 stream state: eof stream state: eof Failed to read int
So you might actually want to check that eof flag to see if you read the entire stream.
As noted by others, of course constructing a new stream object each loop also means no concerns over previous flags/states.