I use !(cin >> input) to validate integer input, but it does not catch other datatypes such as floats. Instead it takes the first whole number. EG:
Please enter a number: 2.5.
My error message appears here, it is suppose to loop round but it takes first number instead.
Outputs "2"
How do I get it to ignore decimal input?
The input stream considers anything starting with a sign followed by at least one decimal digit to be a valid integer input. If you want to fail on a decimal input including a decimal point, you need to do something different. One way to deal with this to read an integer and see if the character following the successful read of an integer is a decimal point:
if (!(std::cin >> value)
|| std::cin.peek() == std::char_traits<char>::to_int_type('.')) {
deal_with_invalid_input(std::cin);
}
As Thomas Matthews correctly pointed out, the problem isn't really limited to floating point numbers but anything with a prefix of digits followed by a non-space (and not EOF: the above solution would actually miss a valid integer at the very end of a file, i.e., not followed by anything, not even a newline). To only read integers followed by a space or at the end of a file, something like this would be in order:
if (!(std:cin >> value)
|| (!std::isspace(std::cin.peek())
&& std::cin.peek() != std::char_traits<char>::eof())) {
deal_with_invalid_input(std::cin);
}
There isn't really any way to return the already read characters. Since this isn't really nice to be used in many places, it may be reasonable to package this function into a suitable std::num_get<char> facet and imbue() the stream with a corresponding std::locale. This is a bit more advanced although the expression to deal with the code is actually simpler.
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