Почему следующий код C ++ сохраняет вывод «неверные данные, попробуйте еще раз»? - PullRequest
2 голосов
/ 28 ноября 2010
int main()
{
        int temp;
        while (cin>>temp, !cin.eof())
        {
                if (cin.bad())
                {
                        throw runtime_error("IO stream corrupted");
                }

                if (cin.fail())
                {
                        cerr<<"bad data, try again";
                        cin.clear(istream::failbit);
                        continue;
                }
        }

        return 0;
}

Если я введу x, то Enter, будет вывод:

, попробуйте снова плохие данные, попробуйте снова плохие данные, попробуйте aa, попробуйте снова плохие данные, попробуйте снова плохие данные, попробуйте снова, попробуйте снова плохие данные, попробуйте снова плохие данные, попробуйте снова, попробуйте снова попали в плохие данные, попробуйте снова попали в плохие данные, попробуйте данные снова, попробуйте снова плохие данные, попробуйте снова плохие данные, t

Почему?

Ответы [ 6 ]

5 голосов
/ 28 ноября 2010

Метод ios :: clear () фактически заменяет биты состояния управления потоком своим аргументом. Вы устанавливаете cin состояние управления на fail каждый раз, когда вы выдаете cin.clear(istream::failbit);.

Вы должны просто позвонить cin.clear();, без аргументов. Это сбросит состояние управления потоком на good.

РЕДАКТИРОВАТЬ: Боже мой, я забыл.

Вам также необходимо вызвать istream :: ignore () , чтобы отменить неверный x токен, который вы только что ввели, поскольку clear() не сбрасывает ожидающий ввод:

if (cin.fail()) {
    cerr << "bad data, try again\n";
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    continue;
}
3 голосов
/ 28 ноября 2010

Поскольку x не является целым числом, оператор operator>> ничего не читает, поэтому при сбросе бита и повторной попытке происходит то же самое.

2 голосов
/ 28 ноября 2010

Вы не очистили () поток.

2 голосов
/ 28 ноября 2010

Если вы используете форматированный ввод / вывод, данные должны совпадать.x не является целым числом.Попробуйте ввести 5 Enter.Или определите temp как std::string.

1 голос
/ 28 ноября 2010

Это связано с данными, которые все еще находятся во входном буфере.cin.clear() просто очищает состояние ошибки cin вместо очистки буфера.Попробуйте сделать что-то вроде этого:

int main()
{
        int temp;
        while (cin>>temp, !cin.eof())
        {
                if (cin.bad())
                {
                        throw runtime_error("IO stream corrupted");
                }

                if (cin.fail())
                {
                        cerr<<"bad data, try again";
                        cin.clear();
                        cin.sync();
                        continue;
                }
        }

        return 0;
}

cin.sync() эффективно очистит буфер для вас.Для получения дополнительной информации см. http://www.cplusplus.com/reference/iostream/istream/sync/.

0 голосов
/ 28 ноября 2010

Потому что ваш цикл закончится только тогда, когда достигнут конец файла. Но если вы попытаетесь прочитать число, в котором есть альфа-символ, cin потерпит неудачу, но eof не будет достигнут Он не сможет прочитать число снова и снова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...