Бесконечная петля
Программа ниже работает большую часть времени. Однако я замечаю, что после использования цикла несколько раз программа переходит в бесконечный цикл вместо выхода из программы, когда я нажимаю клавишу кроме 1. Например, я могу ввести 1, чтобы ввести новый балл, а затем нажать любую другую клавишу для выхода из программы до 3 итераций. Тем не менее, он стремится перейти в бесконечный цикл после третьей итерации вместо выхода из программы, когда я нажимаю клавишу, отличную от 1. Как я могу разрешить эту тенденцию вводить бесконечный цикл?
#include<iostream>
using namespace std;
//Print grade for the score
void printGrade(double score)
{
if (score >= 90)
cout << 'A';
else if (score >= 80.0)
cout << 'B';
else if (score >= 70)
cout << 'C';
else if (score >= 60)
cout << 'D';
else
cout << 'F';
}
int main()
{
int answer;
do
{
cout << "Enter a score: ";
double num;
cin >> num;
cout << "\nThe grade is: ";
printGrade(num);
cout << "\n\n";
cout << "Do you want to enter another score (Enter 1 for Yes)? ";
cin >> answer;
}
while(answer == 1);
return 0;
}
Если cin
ожидает ввода определенного типа, но пользователь вводит что-то, что не может быть проанализировано как этот тип, cin
будет помещен в состояние ошибки. Хотя cin
находится в этом состоянии ошибки, все будущие операции ввода с cin
будут терпеть неудачу. Пользователь не будет запрашиваться для ввода, а входные переменные никогда не изменятся. Поэтому answer
никогда не изменится с 1.
Если вы введете целое число, отличное от 1, цикл должен завершиться. Однако, если вы вводите то, что не является целым числом, это вызовет бесконечный цикл.
Чтобы устранить ошибку, сделайте вызов cin.clear()
, но сначала вам нужно проверить, была ли ошибка, и вам также необходимо очистить входной буфер, чтобы одно и то же не повторилось. Лично я считаю, что все дело беспорядочно, и предпочитаю, чтобы все мои данные std::getline
пользователем через std::getline
, который должен только терпеть неудачу при завершении потока. Затем я использую процедуры синтаксического разбора/преобразования строк, чтобы проверить, соответствует ли вход тем типам, которые я ищу.
Используйте cin.ignore()
перед cin
чтобы прочитать его правильно
Всегда проверяйте свой ввод после прочтения, чтобы убедиться, что вход был успешным:
if (!(std::cin >> answer)) {
std:cout << "failed to read input\n";
break;
}
Я предполагаю, что вы поток переходит в состояние отказа, и он ничего не сделает, пока установлен std::ios_base::failbit
. Вы можете использовать std::cin.clear()
чтобы очистить состояние и std::cin.ignore()
чтобы игнорировать следующий (и, возможно, оскорбительный) символ.