Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing implicit conversion in C++

Tags:

c++

I ask the user for an integer input and I do not want to execute code unless it is strictly an integer.

int x;
if(cin >> x)

For instance if the user inputs a double above, the if statement will execute with implicit conversion to an integer. Instead I don't want the code to execute at all.

How can I prevent this?

like image 700
Mars Avatar asked Dec 26 '22 21:12

Mars


1 Answers

There is no conversion there. If the user enters a fraction (there is no double), then the >> extraction stops at the decimal point.

http://ideone.com/azdOrO

int main() {
    int x;
    std::cin >> x;
    std::cout << std::cin.rdbuf();
}

 input:

123.456

output:

.456

If you want to flag the existence of the decimal point as an error, you will have to do something to extract it from cin and detect it.

One good parsing strategy with C++ streams is to getline what you know you will process into an istringstream, call it s, then check that that s.peek() == std::char_traits<char>::eof() when you finish. If you don't use getline to pull the individual number, then peek can check whether the next character is a space (using std::isspace) without consuming that character from the stream.

Probably the cleanest way to check that input is finished, although it's somewhat esoteric, is to use std::istream::sentry.

if ( ! ( std::cin >> x ) || std::istream::sentry( std::cin ) ) {
    std::cerr << "Invalid or excessive input.\n";
}

This consumes space at the end of the input. sentry also provides a noskipws option to avoid consuming the space.

if ( ! ( std::cin >> x ) || std::istream::sentry( std::cin, true ) ) {
    std::cerr << "Invalid or excessive input. (No space allowed at end!)\n";
}
like image 81
Potatoswatter Avatar answered Feb 05 '23 22:02

Potatoswatter