2015-12-22 4 views
3

В этом цикле пользователь должен ввести int, и программа проверяет, будет ли это странно, что он перейдет к следующим частям, но я не могу понять, почему, если пользователь вводит символ, который не является int , программа попадает в бесконечный цикл!do-while бесконечный цикл с if C++

int num; 
do { 
    cout << "PLEASE enter the num: "; 
    cin >> num; 
    if (num % 2 == 0) 
     cout << "Number should be odd!" << endl; 
    else 
     break; 
} while (true); 
//... 

Причина в любом случае char/int != 0 и если это ==0 тоже должен остановиться на следующем cin но это не остановит! Я тоже пробовал ws(cin), но это мне не помогло. Пожалуйста, расскажите мне, как я могу исправить эту проблему и почему это происходит.

+2

См. [Это] (http://stackoverflow.com/questions/13378989/why-does-stringstream-change-value-of-target-on-failure). – LogicStuff

ответ

4

Beçue ваша программа не проверяет результат cin >> num;. Поскольку cin >> num; (где num - целое число) будет читать все доступные цифры, а если вход не является цифрой вообще [а не пробельный символ, который пропускается на cin >>], то он постоянно пытается прочитать ввод.

Это не ясно из вашего вопроса, то, что вы хотите делать, когда пользователь ввел «askjhrgAERY8IWE» к вашей программе - есть два решения, которые приходят на ум:

Alt 1. Спросите снова после удаления блуждающего вход. Вероятно, это правильно для этого приложения, так как оно является интерактивным, но ужасная идея для автоматической программы, которая считывает свой ввод из файла.

if(!(cin >> num)) 
{ 
    cout << "That deoesn't seem to be a number..." << endl; 
    cin.clear(); 
    cin.ignore(10000, '\n'); 
} 

Alt 2. Выход с сообщением об ошибке. Это, безусловно, правильно, когда типичный ввод - это файл данных.

if(!(cin >> num)) 
{ 
     cout << "That deoesn't seem to be a number..." << endl; 
     exit(1); 
} 

Вы также должны добавить код, чтобы иметь дело с концом файла в этом коде - для файлового ввода, который должен быть приемлем [если файл не имеет конкретные данные, чтобы отметить конец]. Для интерактивного ввода (когда пользователь печатает непосредственно в программе) конец файла может считаться ошибкой или не может считаться ошибкой - действительно зависит от того, что произойдет дальше.

+0

Я думаю, что вы случайно произнесли несколько слов в конце своего ответа. – BoBTFish

+0

@BoBTFish: Спасибо, обычная «преждевременная публикация». –

+0

Я пробовал то, что вы сказали, но '! Cin >> num' не был' True', когда я ввел 'abcd' слишком –

0

В вашей программе стандартный поток ввода ожидает целое число. Когда вы даете ему символ, cin не может помещать его в целочисленную переменную, т. Е. Он терпит неудачу (установлен флаг ошибки) и оставляет введенный символ в буфере (для следующих назначений cin). CIN неоднократно рассматривает характер в качестве входных данных и сохраняет неудачу и целочисленные переменные присваиваются значение 0.

Чтобы предотвратить это вы можете изменить вашу программу как

int num; 
    do{ 
     cout << "PLEASE enter the num: "; 
     while(!(cin>>num)){ 
     cin.clear(); 
     cin.ignore(INT_MAX,'\n'); 
     cout<<"Invalid. Enter a number"; 
    } 
     if (num % 2 == 0) 
      cout << "Number should be odd!" << endl; 
     else 
      break; 
    } 
while(true); 

включает limits.h для использования INT_MAX или вы можете используйте большое значение, подобное 10000.

cin.clear очищает флаг ошибки и делает его готовым к вводу. cin.ignore(INT_MAX,'\n') игнорирует все (до INT_MAX символов) до следующей новой строки. Это гарантирует, что программа будет работать нормально, если пользователь вводит длинную строку вместо числа.

+0

Это не поможет, если пользователь напишет '1abc', программа примет его и пройдет цикл, но мне нужно только тогда, когда вход NUMBER и ODD проходят цикл. –

0

я нашел способ решить мою проблему, я изменил тип входа в string и сделал функцию, как удар:

int isNum(string input) 
{ 
    int digit, value = 0; 
    for (int i = 0; i < input.length(); i++) 
    { 
     digit = input[i] - '0'; 
     if (digit >= 0 && digit <= 9) 
      value = value * 10 + digit; 
     else 
     { 
      value = 0; 
      break; 
     } 
    } 
    return value; 
} 

будет возвращать вклад в int, если все символы находиться в диапазоне от 0 до 9, и иначе мне будет return 0;, поэтому я использую возвращенный int как мой num.