3
votes

When cin>>(int) and cin>>(string) are called, when the first input is not correct for integer, it seems that cin>>(string) will fail to retrieve the second input even if it is correct string.

The source code is simple as:

cout<<"Please enter count and name"<<endl;;
int count;
cin>>count;     // >> reads an integer into count
string name;
cin>>name;      // >> reades a string into name

cout<<"count: "<<count<<endl;
cout<<"name: "<<name<<endl;

The test cases are:

Case 1: Type characters(which not fit for int) and characters

Please enter count and name

ad st

count: 0

name:

Case 2: Type numbers and characters

Please enter count and name

30 ad

count: 30

name: ad

Case 3: Type numbers and numbers (which could be taken as strings)

Please enter count and name

20 33

count: 20

name: 33

2
std::cin has a state that you can inspect eg via std::cin.good(). Input can fail, and often it does, so you need to do something about it - 463035818_is_not_a_number
how can state/result from first use of cin affect second use of cin? Or does it mean that before every use of cin, need to check or clear state of cin? I have never seen any pre-handling of cin state in code. Thanks. - lst
@lst 1) "how can state/result from first use of cin affect second use of cin?" If cin is in an invalid state, any further operations are meaningless. 2) "Or does it mean that before every use of cin, need to check or clear state of cin?" Yes, one needs to get into habit of checking that operations succeeded, instead of assuming that they did. 3) "I have never seen any pre-handling of cin state in code" if (cin>>count) {/* operation succeeded */ } - Algirdas Preidžius

2 Answers

6
votes

A stream has an internal error flag that, once set, remains set until you explicitly clear it. When a read fails, e.g. because the input could not be converted to the required type, the error flag is set, and any subsequent reading operation will not even be tried as long as you do not clear this flag:

int main() {

    stringstream ss("john 123");

    int testInt;
    string testString;

    ss >> testInt;
    if (ss) {
        cout << "good!" << testInt << endl;
    } else {
        cout << "bad!" << endl;
    }

    ss >> testString;
    if (ss) {
        cout << "good!" << testString << endl;
    } else {
        cout << "bad!" << endl;
    }

    ss.clear();
    ss >> testString;
    if (ss) {
        cout << "good:" << testString << endl;
    } else {
        cout << "bad!";
    }
}

Output:

bad!
bad!
good:john
0
votes

You can check for the input statement if it is succeeded or not with the

cin.good() method

If the input statement fails it returns false else true. Here is a small example:

#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
  int x; 

  // prompt the user for input 
  cout << "Enter an integer: " << "\n"; 
  cout << "cin.good() value: " << cin.good() << "\n";
  // get input 
  cin >> x; 
  cout << "cin.good() value: " << cin.good() << "\n";
  // check and see if the input statement succeeded 
  if (!cin) { 
    cout << "That was not an integer." << endl; 
    return EXIT_FAILURE; 
  } 

  // print the value we got from the user 
  cout << x << endl; 
  return EXIT_SUCCESS; 
}

Output:

Enter an integer: 
cin.good() value: 1
asd
cin.good() value: 0
That was not an integer.