Simple input validation: I dont understand this code by Stroustrup

From his 2009 book.
The problem is to get an int input from the console in range [1:10]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cout "Please enter an integer in the range 1 to 10 inclusive: \n";
int n=0;

while(true){
 cin >> n;
 if (cin){ //we got an int, now check it
    if( 1<=n && n <=10) break;
    cout << "Sorry " <<n << "is not in the (1:10] range; please try again \n";
 }
 else if (cin.fail()){//we found something that wasnt an integer
      cin.clear()                //set the state back to good();
                      //we want to look at the characters
      cout <<"Sorry that was not a number; please try again \n";
      char ch;
      while(cin >> ch && !isdigit(ch)); //throw away non digits
      if (!cin) error("no input"); //we didnt find a digit, give up
      cin.unget(); //put the digit back to that we can read the number
  }
  else{
        error("no input"); //eof or bad; give up
  }
}

//Stroustrup defines error() as  a wrapper for throwing an exception 


I dont get the else if part. If a non-number is encountered, it first prints a
"Please try again", then skips over characters to try to get to an int.
But if it can get to an int by skipping over chars, why ask the user to try again?
Eg, if I enter "aaaa" follwed by the enter key, then if I understand it correctly, the program will exit by error()

BTW, any difference if I use cout <<endl; instead of "\n"
Last edited on
Bump...anyone?
The if( 1<=n && n <=10) is checking if the input is a number that was less than 1 or greater than 10. If it is, then the "Please try again" line. The next part is checking if the input was not a number, but a character or punctuation. That's what the cin.fail is for. And if ch is empty, it means there was no input
If you enter "aaaa" followed by the enter key, the program will print "Sorry that was not a number; please try again", and then will wait for input

The mini-loop at line 15 eats up all the 'a's, and then waits for additional input. If the user enters more non-digit letters, it will eat them up silently, and wait for more.

If the user now enters a digit, it unget()'s it, and loops back to line 5 where proper integer input occurs.


As for cout << endl;, it calls a function which executes cout << '\n', and then calls cout.flush(). Besides being unnecessary and complicated, in this program, such call to flush() would be redundant because cout.flush() is also called by cin >> ch and by cin >> n.
The mini-loop at line 15 eats up all the 'a's, and then waits for additional input. If the user enters more non-digit letters, it will eat them up silently, and wait for more.

If the user now enters a digit, it unget()'s it, and loops back to line 5 where proper integer input occurs.


This is the part which is confusing me.

Suppose I type "aaaa 15" and press enter.
Then, is the program supposed to output "Sorry that was not a number; please try again", and then silently accept 15 as n?

I am confused on what would go wrong if lines 14-17 were not present.
is the program supposed to output "Sorry that was not a number; please try again", and then silently accept 15 as n?

Yes, that's exactly what it does.

what would go wrong if lines 14-17 were not present.

That would be an endless loop, endlessly attempting to parse "aaaa" as an integer at line 5, failing, clearing the error, asking to try again, and going back to attempting to parse the same input
[quote]what would go wrong if lines 14-17 were not present.

That would be an endless loop, endlessly attempting to parse "aaaa" as an integer at line 5, failing, clearing the error, asking to try again, and going back to attempting to parse the same input[/quote]

Ah. So if I have a cin to int and input "aaaa", the "aaaa" is not consumed at all?

Thanks.
Topic archived. No new replies allowed.