23

What is the correct way to use cin.fail();?

I am making a program where you need to input something. It is not very clear if you need to input a number or character. When a user inputs a character instead of a number the console goes crazy. How can I use cin.fail() to fix this?

Or is there a better way?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574

2 Answers2

26

std::cin.fail() is used to test whether the preceding input succeeded. It is, however, more idiomatic to just use the stream as if it were a boolean:

if ( std::cin ) {
    //  last input succeeded, i.e. !std::cin.fail()
}

if ( !std::cin ) {
    //  last input failed, i.e. std::cin.fail()
}

In contexts where the syntax of the input permit either a number of a character, the usual solution is to read it by lines (or in some other string form), and parse it; when you detect that there is a number, you can use an std::istringstream to convert it, or any number of other alternatives (strtol, or std::stoi if you have C++11).

It is, however, possible to extract the data directly from the stream:

bool isNumeric;
std::string stringValue;
double numericValue;
if ( std::cin >> numericValue ) {
    isNumeric = true;
} else {
    isNumeric = false;
    std::cin.clear();
    if ( !(std::cin >> stringValue) ) {
        //  Shouldn't get here.
    }
}
James Kanze
  • 150,581
  • 18
  • 184
  • 329
12

cin.fail() returns true if the last cin command failed, and false otherwise.

An example:

int main() {
  int i, j = 0;

  while (1) {
    i++;
    cin >> j;
    if (cin.fail()) return 0;
    cout << "Integer " << i << ": " << j << endl;  
  }
}

Now suppose you have a text file - input.txt and it's contents are:

  30 40 50 60 70 -100 Fred 99 88 77 66

When you will run above short program on that, it will result like:

  Integer 1: 30
  Integer 2: 40
  Integer 3: 50
  Integer 4: 60
  Integer 5: 70
  Integer 6: -100

it will not continue after 6th value as it quits after reading the seventh word, because that is not an integer: cin.fail() returns true.

pensono
  • 336
  • 6
  • 17
Shumail
  • 3,103
  • 4
  • 28
  • 35