2011-12-17 2 views
0

Я изучаю C++.C++ Infinite Loop

nav - целое число.

Я хочу попросить пользователя ввести действительное значение, если он/она напечатает недопустимое значение.

void main() 
{ 
    printf("Type an integer : "); 
    if(!scanf("%d", &nav)) 
    { 
     system("cls"); 
     printf("Invalid ! \n"); 
     main(); 
    } 
} 

Но оно мигает после ввода первого значения. Он мигает, как экран перезагрузки. Я думаю, что это бесконечный цикл.

Как я могу сделать это правильно? Я хочу спросить номер у пользователей, пока он не наберет реальный номер.

+0

рекурсивного вызова основной() это немного странно. – JustJeff

+7

1) 'void main()' является незаконным в C++. 2) вызов 'main()' является незаконным в C++. –

ответ

3

Если пользователь вводит недопустимый ввод, scanf() не будет его использовать, и вы останетесь навсегда, оставив тот же самый символ нарушения. Вы должны сначала прочитать все, что вводит пользователь. Я рекомендую использовать std::getline(), а затем попытайтесь проанализировать это с помощью strtol(), sscanf() или std::istringstream. Не используйте atoi(), потому что он не сообщает о сбоях.

int nav; 
{ 
    string line; 
    while (getline(cin, line)) 
     if (istringstream(line) >> nav) 
      break; 
} 

EDIT: Смотрите комментарии к довольно красивым исполнением вышеприведенной логики. Я оставил его вне ответа, потому что: а) я не хочу воровать чужую идею, и б) я не уверен, что я представил новичка на C++ с этой формулировкой - не в один наименее.

P.S .: Вы не можете позвонить main() в C++.

+0

есть главный в главном :) – fazo

+0

@Marcelo Cantos, спасибо, но можете ли вы дать мне пример использования для моего исходного кода? Я начинаю изучать C++, и я не мог адаптировать это к моим кодам. – Eray

+1

Вы можете записать это в 'for (std :: string line; std :: getline (std :: cin, line) &&! (Std :: istringstream (строка) >> nav);) {}'. –

1

Две вещи.

Scanf требует нажатия клавиши ввода, прежде чем он будет обрабатывать ввод, поэтому мигание может быть только курсором, ожидающим следующей клавиши.

Кроме того, вызов main из основного является довольно нестандартным. Вы должны заглянуть в цикл while.

+0

«мигание может быть просто курсором, ожидающим следующую клавишу». Нет, нет, весь экран мигает, например, перезагружает экран. – Eray

+0

Тогда я думаю, что два других ответа верны. , Если символ, ожидающий входного буфера, не совпадает, он не удаляется, а когда вы выполняете следующий scanf, вы получаете его снова и снова очищаете экран и снова и снова. – AShelly

0

Ваша программа не очень хорошая, но, тем не менее, я расскажу вам, что происходит.

В C/C++, когда scanf не может прочитать целое число (%d) с ввода, он ничего не прочитает. То есть, все, что помешало scanf от чтения int, останется там. В следующем scanf тот же символ будет вызывать ошибку.

Позвольте мне продемонстрировать на примере. Представьте, что вы читаете много целых чисел от этого входа:

12 13 Shahbaz 15 

Теперь, если вы звоните scanf с %d, вы прочтете 12 и вход будет:

13 Shahbaz 15 

Далее вы звоните scanf с %d и вы будете читать 13. Теперь вход будет:

Shahbaz 15 

Опять же, вы звоните scanf с %d.Здесь ввод начинается с S (после пробела), который возвращает scanf с отказом, поскольку он не может прочитать целое число. Вход остается нетронутым (за исключением, возможно, пробела). То есть, вход будет:

Shahbaz 15 

Как вы можете видеть, читать вход с %d даст вам точно такие же ошибки, и вы застряли в бесконечном цикле.

Чтобы решить эту проблему, у вас есть много вариантов. Это очень зависит от того, как вы хотите справиться с ситуацией, но два метода - либо прочитать символ (с %c), либо строку (с %s) сразу после печати printf("Invalid\n").

Первый способ хорош для обработки ввода, как это:

12 13 q14 15 

где q ошибка, которая должна быть проигнорировано. Второй метод хорош для обработки ввода, как это:

12 13 Shahbaz 15 

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

И путь я бы написать, если бы я хотел использовать scanf бы:

int main() // always write int main 
{ 
    int nav; 
    printf("Type an integer: "); 
    while (scanf("%d", &nav) != 1) // scanf returns number of successful %'s read 
    { 
     printf("Invalid number. Try again: "); 
     scanf("%*s");    // read a %s but ignore it 
    } 
    // The rest of the program, using nav 
    return 0; 
} 
+0

И почему проголосовать ?! – Shahbaz