The following code snippet is taken from C Iostreams Handbook by Steve Teale
. It suggests invoking cin in an endless loop so that the user is continuously prompted for the correct input, and only when the correct input is entered do we exit the loop.
This code snippet works correctly but I am confused by the if(cin){...}
statement. I would have expected something like if(!cin.fail()){...}
.
#include <limits.h>
#include <iostream>
using namespace std;
int main()
{
int n;
cin.unsetf(ios::skipws);
// turn off whitespece skipping
cout << "Enter a value for n, followed by [Enter]: " << flush;
for(;;) {
cin >> n;
if(cin) { //cin is in good state; input was ok
cin.ignore(INT_MAX, '\n');
// flush away the unwanted
// newline character
break;
}
// Poster's comment (not from the author)
// In this section of the code cin has evaluated to false
//
cin.clear(); // clear the error state
cin.ignore(INT_MAX, '\n');
// get rid of garbage characters
cout << "That was no good, try again: " << flush;
}
return 0;
}
Q) How does cin evaluate to false (i.e. a zero or null value) in the event of a failure?
cin is an object, not a pointer that could be set to null. Furthermore, in the section of code where cin evaluates to false we can still invoke member functions like clear
and ignore
.
CodePudding user response:
What you're observing is a result of inheritance and implicit conversion. More specifically, std::cin
has an operator bool()
that converts the state of the stream to a boolean and that operator returns !fail()
.
std::cin
is a global std::basic_istream
provided by the standard lib, and basic_istream
inherits from std::basic_ios
which defines the function operator bool()
The chain of inheritance is:
std::ios_base <-- std::basic_ios <-- std::basic_istream
You may find the table at the bottom of this webpage useful to compare operator bool()
to the other state checking functions of the stream and the streams' different status flags.