Search code examples
c++stringstream

C++ various results of stringstream inputs


I was trying out a program of 'stringstream' which goes like this :

#include <iostream>
#include <sstream>
using namespace std;
int main()
{
int x;
char ch;
std::string myString;
cout<< "input an integer:-" << endl;
while (getline ( cin, myString ))
{
    std::istringstream strin(myString);
    strin >> x;
    if (!strin)
    {
        cout << "Bad 1 input \'" << strin.str() << "\'" << endl;
    }
    else if ( strin >> ch )
       {
           cout << "Bad 2 input \'" << ch << "\'" << endl;
       }
    else
        {
            cout << "You entered: " << x << endl;
            break;
        }
}
cout<< "good";
return 0;
}

OUTPUT :

input an integer:-
he is there
Bad 1 input 'he is there'
5.0
Bad 2 input '.'                 // problem 1
2 3
Bad 2 input '3'                 // problem 2
2 string
Bad 2 input 's'                 // problem 3
c string
Bad 1 input 'c string'
string 2
Bad 1 input 'string 2'          // problem 4
5
You entered: 5
good

As i have marked my problems here they go :

Problem 1 : why isn't bad input 1 thrown here ? also why does ch equal '.' and not 0 if bad input 2 is thrown ?

Problem 2 : why isn't bad input 1 thrown ? why ch equals 3 ?

Problem 3 : why isn't bad input 1 thrown (again) ? (this also asks why output gives 's' and not '2 string')

Problem 4 : why output isn't similar to problem 3 ?

I am unable to figure out why this happens.


Solution

  • Stringstream parses the input on a character-wise basis. If it starts to parse an int, which is what happens during problems #1-3, it won't be throwing badinput 1.

    The process which it uses is this.

    1. Is first character a digit (or sign)?
      • If yes, store and continue, otherwise, error one;
    2. Is next character a digit?
      • if Yes, store, and continue, running step two over again.
      • if no, is it the terminal character i.e. '\0' or whitespace
        • If it is, good., but if it's whitespace, if there's any other characters, besides '\0' or more whitespace, error two.
        • Else, error two.

    Therefore, in problem #:

    1. Since the first character is a digit (5), error one is avoided. But since the second is '.', it encountered a bad character before the end of the input.
    2. The first character is a digit (2), so error one is avoided. But the next character is a space which is followed by '3', which can't make an int, causing error 2.
    3. The first character is '2', a digit. No error here. Then you have a space, followed by 's'. No int here. Error 2.
    4. Here, the first character is 's', which is obviously not a digit. Error 1.