Something like
cin >> Delay1;
if(cin) { ... }
won't work according to your specification, because cin
will skip leading whitespace. The user can't just hit enter. He first has to enter some text. If he enters the following
3a
Then the input is read into the double, up to a
, where it stops. cin
won't find anything wrong, and leaves a
in the stream. Often, this is enough error handling, i think. But if it's a requirement that you want to actually repeat when the user enters something like above, then you need a bit more code.
If you want to test whether the whole input up to the newline is a number, then you should use getline
, read into a string and then try to convert to a number
string delay;
if(!getline(std::cin, delay) || !isnumber(delay)) {
...
}
The isnumber
function can use a stringstream to test the string
bool isnumber(string const &str) {
std::istringstream ss(str);
double d;
// allow leading and trailing whitespace, but no garbage
return (ss >> d) && (ss >> std::ws).eof();
}
The operator>>
will eat leading whitespace, and std::ws
will consume trailing whitespace. If it hits to the end of the stream, it will signal eof
. This way, you can signal the error to the user immediately, instead of erroring out at the next time you try to read from cin
.
Write a similar function that returns the double or pass the address of a double to `isnumber, so that it can write the result in case of a successful parse.
It's also worth to have a look at the various error flags and how they relate to operator void*
, operator!
, good()
, fail()
, bad()
and eof()
which can be quite confusing:
flag | badbit | failbit | eofbit
function | | |
-----------------+---------+-----------+--------
op void* | x | x |
-----------------+---------+-----------+--------
op ! | x | x |
-----------------+---------+-----------+--------
good() | x | x | x
-----------------+---------+-----------+--------
fail() | x | x |
-----------------+---------+-----------+--------
bad() | x | |
-----------------+---------+-----------+--------
eof() | | | x
-----------------+---------+-----------+--------
There is an x
if the respective bit influences the result. operator void*
is used when converting to bool
(if(cin) ...
) while operator!
is used for code doing !cin