#include <iostream>
#include <ctime>
#include <conio.h>
#include <string>
#define NOMINMAX
#include <limits>
#include <windows.h>
using namespace std;
void delay(double delaySec) {
clock_t delayClock = delaySec * CLOCKS_PER_SEC;
clock_t start = clock();
while (clock() - start < delayClock);
}
int main() {
setlocale(LC_ALL, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
char ch;
double delaySec;
string phrase;
cin.exceptions(istream::failbit | istream::badbit);
do {
cout << "Введите время задержки в секундах: ";
try {
cin >> delaySec;
}
catch (istream::failure exp) {
cout << "Введите число!\n";
cin >> delaySec;
}
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Введите фразу: ";
getline(cin, phrase);
delay(delaySec);
cout << "Фраза: " << phrase << endl;
} while (delaySec != 0);
_getch();
return 0;
}
Если ввести не число, то выводится строка "Введите число", а потом выбрасывается исключение в строке cin >> delaySec
в блоке catch:
Возникло необработанное исключение по адресу 0x74EAAA12 в Delay2.exe: исключение Microsoft C++: std::ios_base::failure по адресу памяти 0x005BEB14
Почему это происходит и как это исправить?
Разумеется, выбрасывается.
Во-первых, когда в процессе первого cin >> delaySec
возникла ошибка и в потоке cin
выставился флаг failbit
, сам по себе этот флаг сбрасываться не будет. Поток cin
переходит в перманентное ошибочное состояние. Вывести его из этого состояния, т.е. очистить флаги ошибок, можете только вы явным образом, например через вызов cin.clear()
.
Если поток находится в режиме выбрасывания исключений по каким-то флагам (как в вашем примере), то пока эти флаги не сброшены, все попытки чтения из данного потока будут мгновенно выбрасывать исключения, независимо от того, правильные данные вы подадите на вход или неправильные.
Вы флаг failbit
нигде не сбрасываете. Поэтому в вашем случае второй cin >> delaySec
не будет даже пытаться ничего читать из потока, а вместо этого сразу же снова выбросит fail-исключение, которые вы не ловите. Его вы и видите.
Во-вторых, даже если вы сделаете cin.clear()
, вам все равно еще нужно убрать из входного потока ошибочные входные данные. Если вы этого не сделаете, то вторая попытка cin >> delaySec
будет пытаться читать все тот же неправильный вход. В результате опять произойдет та же самая ошибка и выбросится то же самое исключение.
Я вижу, вы вставили в код чистку буфера от неправильного ввода
cin.ignore(numeric_limits<streamsize>::max(), '\n');
но попытку повторного чтения cin >> delaySec
вы делаете еще до чистки буфера. Должно быть наоборот: чистить буфер нужно до повторной попытки чтения. (А cin.clear()
нужно сделать до cin.ignore()
.)
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Есть сайт, которую перенесли с Wordpress на ModXПосле чего форма отправки заявок перестала работать
Пытаюся создать простой блог не не как не могу добовлять статьи по сути готовая версия уже есть но нужно сделать это все одним классом во viespy...
Столкнулся проблемной, что vk при отправки ссылки главной страницы http://alisa-musicru/ отображает не заданный <meta property="og:title" content="Все песни Алисы...
На сайте есть форма для регистрацииПри нажатии на кнопку "Зарегистрироваться" должна быть анимация, но она не успевает проиграться, потому...