Есть гораздо больше способов неправильно использовать scanf
в цикле, что собственно из них. Основная проблема (помимо ввода или сопоставлением неудач, которые описаны в странице человека), не в состоянии очистить входной буфер (stdin
при чтении из терминала) после неудачной попытки преобразования. (Существует также проблема, что пользователь должен что-то ввести.) Когда пользователь вводит текст и нажимает [Enter]
, newline
('\n'
) генерируется и помещается во входной буфер, чтобы отметить конец строки. При вводе a, 5.4, c
, 'a'
прекрасно, но 5.4
не является int
и обработка терпит неудачу:
Если обработка директивы неудачна, то дальнейший ввод не считывается, и Scanf() возвращает.
Когда scanf
возвращается, он оставляет остальные символы в stdin
и вы петлю и попытаться снова читать. scanf
пытается прочитать то, что осталось в stdin
, обработка снова завершается неудачно, и цикл продолжается бесконечно.
В этой ситуации единственный способ предотвратить неопределенный цикл - это вручную очистить входной буфер после вызова scanf
. Что-то простое будет делать:
int c;
...
while (...) {
scanf (...)
while ((c = getchar()) != '\n' && c != EOF) {}
}
Это гарантирует, что вы начнете с пустого буфера на следующей итерации.Например:
#include <stdio.h>
int main (void) {
int num1 ,num2, c;
char str;
while (printf ("\nEnter : ") &&
scanf (" %d, %d, %c%*c", &num1, &num2, &str) != 3) {
printf ("error: invalid input, required: 'int, int, char'\n");
/* empty remaining chars from input buffer */
while ((c = getchar()) != '\n' && c != EOF) {}
}
printf ("\n num1 : %d\n num2 : %d\n str : %c\n\n", num1, num2, str);
return 0;
}
Пример использования
$./bin/scanf3
Enter : a
error: invalid input, required: 'int, int, char'
Enter : a, 5.4, c
error: invalid input, required: 'int, int, char'
Enter : 10, 25
error: invalid input, required: 'int, int, char'
Enter : 10, 25, a
num1 : 10
num2 : 25
str : a
Примечание: это не защищает от входа пользователя ничего (просто нажав [Enter]
), а курсор просто сидит там мигает, как он ждет вход. Это неотъемлемое поведение scanf
, часть которого является причиной того, что методы ввода ориентированы на линию методы ввода (fgets
или getline
) предпочтительны при вводе.
Поскольку 'scanf' не использует вход, если он не соответствует. Таким образом, ваш код постоянно пытается разобрать один и тот же ввод (который никогда не будет успешным). – kaylum
вы инициализируете main как 'int main (void)', а затем вы не возвращаете значение из main? Где ваше 'возвращение 0'? – JackVanier
Почему вы не используете функцию 'return' – orvi