Question

I have a question on the stream behavior, see the following example. What I was expecting is, since there are only 5 chars in the string, and stream read will get stuck as I am trying to read 10 chars. Instead, the output is "hellooooo" ... the last char get repeated. My questions are two folds: first, why? second, is there anyway to make stream behave as if no more repeating of last char?

#include <sstream>
#include <iostream>
using namespace std;

int main(void) {
    char c;
    string msg("hello");
    istringstream iss(msg);
    unsigned int i = 0;
    while (i < 10) {
        iss >> c;
        cout << c;
        i++;
    }
    cout << endl;
    return 0;
}
Was it helpful?

Solution

What you see is the result of reading form a stream in an erronous state. When you read past the last element in the stream (this being a string stream), the stream becomes erroneous and any other attempt to read from it will fail (and leave the extraction variable untouched).

You will have to check if the extraction operation succeeded before reading further:

if (iss >> c) {
  // succeess
} else {
  // failed to extract, handle error
}

Were you to use a stream connected to the console (for an example) your call to >> would have blocked as you expected. The behavior of stringstream is different (you cannot expect to micraculously contain more data)

OTHER TIPS

The reason is that when you've read to the end of the stream, all attempts to read after that just fail, leaving the last value read in your c.

If you want to read at most 10 characters:

while (i < 10 && is >> c) {
    cout << c;
    i++;
}

This works because a stream can be converted to bool, and it's true if the stream is in a "good" state.

"the last char get repeated"
When iss >> c fails, c stays unmodified.

Check whether extraction of value succeeded by directly evaluating this expression: if (iss >> c), but don't even think about calling iss.good(). Check this answer and also have a look at:
How does that funky while (std::cin >> foo) syntax work?
Why does my input seem to process past the end of file?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top