Правильный способ использования cin.fail()

Каков правильный способ использования cin.fail();?

Я делаю программу, в которой вам нужно что-то вводить. Не совсем понятно, нужно ли вводить число или символ. Когда пользователь вводит символ вместо номера, консоль сходит с ума. Как я могу использовать cin.fail(), чтобы исправить это?

Или есть лучший способ?

Ответ 1

cin.fail() возвращает true, если последняя команда cin не удалась, а false в противном случае.

Пример

int main() {

int i, j = 0;

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

Теперь предположим, что у вас есть текстовый файл - input.txt, и его содержимое:

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

Когда вы запустите над этой программой короткую программу, она будет выглядеть следующим образом:

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

он не будет продолжать после 6-го значения после выхода седьмого слова , потому что это не целое число: cin.fail() содержит true.

Ответ 2

std::cin.fail() используется для проверки того, был ли предыдущий ввод удалось. Тем не менее, более идиоматично использовать поток, как если бы он был логическим:

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

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

В контекстах, где синтаксис ввода допускает либо число символа, обычным решением является чтение его строками (или в некоторая другая строковая форма) и проанализировать его; когда вы обнаруживаете, что есть число, вы можете использовать std::istringstream для конвертировать его или любое количество других альтернатив (strtol, или std::stoi, если у вас есть С++ 11).

Однако можно извлечь данные непосредственно из Поток:

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.
    }
}