Ваша программа не очень хорошая, но, тем не менее, я расскажу вам, что происходит.
В 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;
}
рекурсивного вызова основной() это немного странно. – JustJeff
1) 'void main()' является незаконным в C++. 2) вызов 'main()' является незаконным в C++. –