0

I want to take user input and exit the program if the input is not integer. I checked a program from a book: http://homepages.gac.edu/~mc38/2013J/code/bookCode/ch03/elevator2.cpp

It says that using cin.fail() I can check this. But program doesn't exit even if I input floor type values. e.g. if I input 2.5, the output is 2, instead of my error message "Not an integer".

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
zud
  • 105
  • 2

1 Answers1

0

The problem here is that the character sequence 2.5 clearly starts with a valid integer, i.e., with 2. This is what the stream successfully reads. Thus, after reading 2 there is no reason for the stream to fail.

One way to you could deal with the situation is to read an integer and if this is successful inspect the character which caused the read operation to stop: if this character is a suitable separator, e.g., a space, the end of the file, etc., you consider the input to be successful:

bool is_integer_separator(int value) {
    return value == std::char_traits<char>::eof()           // at the end of the file
        || value == ','                                     // accept comma as separator
        || std::isspace(static_cast<unsigned char>(value)); // ... and space
}

// ...
int value;
if (std::cin >> value && is_integer_separator(std::cin.peek())) {
    ...
}
else {
    std::cout << "Not an integer\n";
}

In general, reading an integer and stopping when a character is encountered which doesn't suit an integer is the desired definition of success. If you need a most customized definition, you can build it from this functionality combined with seeing what is coming next in the stream. The std::istream::peek() member looks at the next character without extracting it. It return std::char_traits<char>::eof() if there is a failure, e.g., the stream was in failure-mode (i.e., it has std::ios_base::failbit or std::ios_base::badbit set) or the end of the file was reached. Since the stream was OK right before this operation the only possible failure is having reached the end of the file. You can then consider whatever character is encountered and determine if you want to accept it. The example considers spaces and ',' as viable separators. Note, that the next character isn't extracted, yet, i.e., you might want to get rid of it, using, e.g., std::cin.ignore().

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380