I found this link at http://www.parashift.com/c++-faq-lite/istream-and-ignore.html
which shows "How can I get std::cin to skip invalid input characters?"
Use std::cin.clear() and std::cin.ignore().
#include <iostream>
#include <limits>
int main()
{
int age = 0;
while ((std::cout << "How old are you? ")
&& !(std::cin >> age)) {
std::cout << "That's not a number; ";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
std::cout << "You are " << age << " years old\n";
...
}
Of course you can also print the error message when the input is out of range. For example, if you wanted the age to be between 1 and 200, you could change the while loop to:
...
while ((std::cout << "How old are you? ")
&& (!(std::cin >> age) || age < 1 || age > 200)) {
std::cout << "That's not a number between 1 and 200; ";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
...
Here's a sample run:
How old are you? foo
That's not a number between 1 and 200; How old are you? bar
That's not a number between 1 and 200; How old are you? -3
That's not a number between 1 and 200; How old are you? 0
That's not a number between 1 and 200; How old are you? 201
That's not a number between 1 and 200; How old are you? 2
You are 2 years old
I am not able to get how it is doing it > Can any one explain please?
I have doubts with :
while ((std::cout << "How old are you? ")
&& !(std::cin >> age))
How is it checking the valid entry? I mean to ask do expressions "std::cout << "How old are you?" and "!(std::cin >> age)" , return true or false which are being ANDed ?
another thing which is confusing is the usage,
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
What are there purpose ? Searched on google about these functions but still I am not clear.
Particularly, std::numeric_limits<std::streamsize>::max()
Can any one help? Thanks
When developing programs there are three types of error that can occur: syntax errors. logic errors. runtime errors.
If our expectation is one thing and result output is other thing then that kind of error we said it as “Logical errors”. Let suppose if we want sum of the 2 numbers but given output is the multiplication of 2 numbers then this said to be Logical error. It can be detected by line by line debugging.
Errors that occur because the compiler is unable to understand the written code are called Semantic Errors. A semantic error will be generated if the code makes no sense to the compiler, even though it is syntactically correct. It is like using the wrong word in the wrong place in the English language.
The insertion and extraction operators <<
and >>
on streams will return a reference to the stream itself. That's why you can string together insertions like so:
std::cout << "Hello, " << "World!";
First std::cout << "Hello, "
returns a reference to std::cout
and then you have the equivalent of std::cout << "World!"
.
The streams can also be converted to bool
. This basically checks that the state of the stream is still okay. Nothing has failed. For example, you could do this:
if (std::cin) // ...
This would check if the std::cin
stream is still in a good state.
Now let's look at the code you asked about:
while ((std::cout << "How old are you? ")
&& !(std::cin >> age))
The insertion into std::cout
won't cause a failure. The only reason it's included here is so that it occurs every time before the input to age
. The alternative would be to place it once before the while
and once at the end of the while
body.
After the insertion to std::cout
is done, !(std::cin >> age)
will be evaluated. This will first get the user to provide an age
. Then two things can happen:
If this fails in some way (perhaps the user enters characters rather than an integer), then the fail bit will be set. This means that the result of std::cin >> age
will be converted to a bool
which will be false
. The !
will invert it to true
. So because both the first and second condition were true, the body of the while
loop will execute, telling the user that they entered an invalid value and the loop will iterate round again.
if the input succeeds, the result of std::cin >> age
will be true
and !
will turn it to false
. This means the body of the while
loop will not execute and will not tell the user that they entered the incorrect value.
Now let's look at:
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
This only happens in case 1 above, when the input failed. If a stream goes into a failure state, it will not accept any more insertions or extractions until the state has been cleared. that's what clear()
does. Then the call to ignore
says to extract all characters up to and including the next \n
in the stream and discard them. This gets rid of the invalid input from the stream.
while ((std::cout << "How old are you? ") && !(std::cin >> age))
cout
is a global object of class ostream
and cin
is a global object of class istream
These objects are used along the overloaded operators <<
(defined in ostream
)and >>
(defined in istream
) to take input (by calling the functions defined for these operators)
The return type of operator<<
is of type ostream&
and that of operator>>
is istream&
. These are then converted to boolean values. See this.
Check this too for cin.ignore()
and cin.clear()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With