Здравствуйте.
Не подскажете, почему failbit не сбрасывается? Вот пример кода:
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int ival;
while (cin >> ival, !cin.eof())
{
if (cin.bad())
throw runtime_error("istream corrupted.");
if (cin.fail())
{
cout << "wrong data. enter again\n";
cin.clear(istream::failbit);
continue;
}
cout << "Your number is: " << ival << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
Если вводишь не число, а например слово (букву), то выставляется failbit, а вот сбрасываться он
никак не хочет. Что я делаю не так? Вроде всё верно. Проверялось на MS VStudio Express 2005.
Заранее спасибо.
Здравствуйте, Astral29, Вы писали:
A>Здравствуйте.
A>Если вводишь не число, а например слово (букву), то выставляется failbit, а вот сбрасываться он
A>никак не хочет. Что я делаю не так? Вроде всё верно. Проверялось на MS VStudio Express 2005.
A>Заранее спасибо.
void clear(
iostate _State=goodbit
);
Parameter_State (optional)
The flags you want to set after clearing all flags.
Наверное, тебе нужно просто clear().
Здравствуйте, Alex Alexandrov, Вы писали:
AA>Здравствуйте, Astral29, Вы писали:
A>>Здравствуйте.
A>>Если вводишь не число, а например слово (букву), то выставляется failbit, а вот сбрасываться он
A>>никак не хочет. Что я делаю не так? Вроде всё верно. Проверялось на MS VStudio Express 2005.
A>>Заранее спасибо.
AA>AA>void clear(
AA> iostate _State=goodbit
AA>);
AA>Parameter_State (optional)
AA>The flags you want to set after clearing all flags.
AA>Наверное, тебе нужно просто clear().
Неа, я и так и сяк пробывал. Не работает
Здравствуйте, Astral29, Вы писали:
AA>>Наверное, тебе нужно просто clear().
A>Неа, я и так и сяк пробывал. Не работает
Нет, нужно именно просто cin.clear(). В том коде, что ты показал ты его не сбрасываешь, а сам повторно устанавливаешь.
Вообще же твоя проблема заключалась в том, что ты хотя и сбрасывал failbit, но не изменял содержимое потока! Неудавшаяся операция чтения целого числа не удаляет некорректные с её точки зрения символы из потока. Поэтому у тебя программа входила в бесконечный цикл: в потоке есть некорректные данные -> пытаемся прочитать их как чило -> исключение -> сбрасываем failbit -> снова считываем некорректные данные (те же самые!). Вот и всё.
Следовательно, в случае ошибки нужно очистить поток ввода, чтобы вводимые тобой символы попадали в чистый поток. А это можно сделать следующим образом:
...
if (cin.fail())
{
cout << "wrong data. enter again\n";
cin.clear();
cin.ignore(static_cast<streamsize>(numeric_limits<int>::max()), '\n');
continue;
}
...
Функция ignore у всех потоков ввода позволяет игнорировать всё текущее содержимое до тех пор, пока не встретится символ, передаваемый вторым параметром, но не более чем количество символов, указанное первым параметром.
В нашем случае символ — перевод строки.
Скобки забыл поставить после max — это функция! ДХ
Здравствуйте, Хитрик Денис, Вы писали:
Прошу прощения, забыл скобки после max:
...
cin.ignore(static_cast<streamsize>(numeric_limits<int>::max()), '\n');
...
Здравствуйте, Хитрик Денис, Вы писали:
ХД>Нет, нужно именно просто cin.clear(). В том коде, что ты показал ты его не сбрасываешь, а сам повторно устанавливаешь.
Это, кстати, практически пример из книги "C++ Вводный курс, 4е издание" С.Липпман
Там ничего про
ignore нет.
ХД>Вообще же твоя проблема заключалась в том, что ты хотя и сбрасывал failbit, но не изменял содержимое потока! Неудавшаяся операция чтения целого числа не удаляет некорректные с её точки зрения символы из потока. Поэтому у тебя программа входила в бесконечный цикл: в потоке есть некорректные данные -> пытаемся прочитать их как чило -> исключение -> сбрасываем failbit -> снова считываем некорректные данные (те же самые!). Вот и всё.
ХД>Следовательно, в случае ошибки нужно очистить поток ввода, чтобы вводимые тобой символы попадали в чистый поток. А это можно сделать следующим образом:
ХД>ХД> ...
ХД> if (cin.fail())
ХД> {
ХД> cout << "wrong data. enter again\n";
ХД> cin.clear();
ХД> cin.ignore(static_cast<streamsize>(numeric_limits<int>::max()), '\n');
ХД> continue;
ХД> }
ХД> ...
ХД>
ХД>Функция ignore у всех потоков ввода позволяет игнорировать всё текущее содержимое до тех пор, пока не встретится символ, передаваемый вторым параметром, но не более чем количество символов, указанное первым параметром.
ХД>В нашем случае символ — перевод строки.
Большое спасибо за ответ.