cin input (input - int), когда я вводю букву, вместо того, чтобы печатать один раз неправильно, она печатает один раз правильно, затем inc для остальной части цикла - PullRequest
0 голосов
/ 18 мая 2018

Я делаю программу тренировки умножения.Как говорится в моем заголовке, если я введу в консоль букву вместо цифры, она будет показывать правильное в первом случае, а в остальных - неверное.Даже если вы не дотрагиваетесь до клавиатуры, она все равно будет отображаться неправильно.

ans = table * i;
                    std::cout << table << " * " << i << " =" << std::endl;
                    std::cin >> input;
                    if(input == ans)
                    {
                            std::cout << "Correct! " << ans << std::endl;
                    }
                    else
                    {
                            std::cout << "Incorrect, the answer was " << ans << std::endl;
                            input = 0;
                            ans = 0;
                    }
            }

Надеюсь, это даст вам представление о том, что происходит в коде.Вот вывод.

Enter the table you'd like to learn.
5
Enter the amount of multiples
3
5 * 0 =
s
Correct! 0
5 * 1 =
Incorrect, the answer was 5
5 * 2 =
Incorrect, the answer was 10
5 * 3 =
Incorrect, the answer was 15

Что я могу сделать, чтобы решить эту проблему?Спасибо за ваш ввод .

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Существует несколько способов структурировать различные тесты, но при вводе с помощью cin (или, как правило, с любой функцией ввода), вы должны учитывать любые символы во входном буфере, которые остаются непрочитанными.С cin у вас есть три условия, которые вы должны проверить:

  1. .eof() (eofbit).Либо был достигнут конец ввода, либо пользователь вручную сгенерировал EOF, нажав Ctrl + d (или Ctrl + z при повороте, но см .: CTRL +Z не генерирует EOF в Windows 10 );

  2. .bad() (badbit).Произошла неисправимая ошибка потока;и

  3. .fail() (failbit).Произошел соответствующий или другой исправимый сбой.Когда происходит сбой , ввод прекращается и никакие дополнительные символы не извлекаются из буфера ввода .

(вы можете объединить 1 и 2 в один тест, когда ввод законченв этот момент)

С failbit вы должны сделать две вещи.(1) вы должны очистить состояние ошибки потока, вызвав cin.clear(), и (2) вы должны обработать любые символы, которые остаются непрочитанными во входном буфере.Обычно это выполняется путем включения <limits> и вызова:

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

(который удалит до INT_MAX символов из входного буфера, останавливаясь при обнаружении разделителя ('\n' здесь))

Короткий пример, который повторяется до тех пор, пока пользователь не введет действительное целое число , может быть:

#include <iostream>
#include <limits>

using namespace std;

int main (void) {

    int x = 0;

    while (1)       /* loop continually until valid input received */
    {
        cout << "\nenter an integer: ";
        if (! (cin >> x) ) {            /* check stream state */
            /* if eof() or bad() break read loop */
            if (cin.eof() || cin.bad()) {
                cerr << "(user canceled or unreconverable error)\n";
                return 1;
            }
            else if (cin.fail()) {      /* if failbit */
                cerr << "error: invalid input.\n";
                cin.clear();            /* clear failbit */
                /* extract any characters that remain unread */
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
            }
        }
        else {  /* on succesful read of int */
                /* extract any characters that remain unread */
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            break;  /* then break read loop */
        }
    }

    cout << "integer: " << x << '\n';
}

(как упоминалось в начале, вы можете структурировать множество тестовдругими способами, если вы охватите все три условия.)

Кроме того, вы можете явно проверить бит потока, вызвав rdstate() вместо тестирования с .fail() и т. д., например

if (std::cin.rdstate() == std::ios_base::failbit)

Пример использования / Вывод

$ ./bin/cin_validate_int

enter an integer: no
error: invalid input.

enter an integer: "an integer"
error: invalid input.

enter an integer: abc 123
error: invalid input.

enter an integer: 123
integer: 123

Просмотрите все и дайте мне знать, если у вас есть дополнительные вопросы.

0 голосов
/ 18 мая 2018

Когда вы делаете cin >> input и он не может проанализировать вход как число, он устанавливает cin s failbit, а когда установлен failbit, на самом деле это не такчитать все данные до тех пор, пока вы их не очистите.

Вам следует проверить ошибки, позвонив по номеру cin.good() и попытаться стереть их с помощью cin.clear(), но выне следует пытаться очистить некоторые ошибки (например, EOF ) и вместо этого следует выходить из них.

...