scanf (% d, ..) в цикле, когда заданный символ один раз не блокирует - PullRequest
4 голосов
/ 30 июня 2011

Я написал этот код:

 char str[10];

    while(1)
    {
       scanf("%d",str);  
    }

если дано char (например, 'a'), цикл просто продолжает работать, не останавливаясь и не запрашивая больше ввода (scanf не блокируется внезапно)

почему это? :-)

Ответы [ 6 ]

3 голосов
/ 30 июня 2011

Потому что a не является десятичным целым числом. scanf попытается прочитать его, но потерпит неудачу и не будет продвигать свой внутренний указатель, поэтому он будет бесконечно пытаться прочитать то же самое a, что и десятичное число, и потерпит неудачу.

рассмотрим следующую программу:

int d;
char c;
scanf("%d", &d);
scanf("%c", &c);

если вы введете a, то первое сканирование не будет выполнено, а второе будет читать «a» в c. Это должно объяснить проблему:)

1 голос
/ 30 июня 2011

Поскольку он не может привести 'a' в целочисленную форму, поэтому он «помещает его обратно в поток» (здесь нет никакого реального потока, только способ речи).Тогда ваш бесконечный цикл заставляет его повторить ту же самую процедуру снова.Бесконечно.

0 голосов
/ 30 июня 2011

Чтобы исправить это, вам нужно проверить, чтобы scanf () действительно считывал нужные значения. scanf () возвращает количество успешно прочитанных элементов. Так что сохраните возвращаемое значение, проверьте, равно ли оно 1. Если это 0, то 0 элементов были прочитаны, и вам нужно очистить поток перед повторной попыткой. (редактировать: ну, возможно, не обязательно очищать его, но, по крайней мере, избавиться от оскорбительных данных в потоке)

Как уже говорили другие, он пытается прочитать целое число, видит 'a', не может прочитать целое число, но затем 'a' все еще находится в потоке при следующей попытке.

0 голосов
/ 30 июня 2011

входной буфер имеет a....

ваш scanf пытается прочитать целое число:

     a....
     ^
     oops : cannot be int. stop scanfing

и в следующем цикле a все еще там.

scanf общеизвестно сложно использовать правильно, но вы должны всегда проверять его возвращаемое значение:

int chk;
chk = scanf(...); /* pseudo-code */
if (chk != EXPECTED_VALUE) { /* HANDLE ERROR! */ }
0 голосов
/ 30 июня 2011

Возможно, он пытается прочитать int, но затем замечает, что в потоке данных нет int, поэтому он немедленно возвращается.Если он не использует входной поток, он будет повторять это.

0 голосов
/ 30 июня 2011

Ваша строка формата %d, а не %s.Scanf() ищет целое число, а не строку.Ваш цикл продолжается вечно, потому что он говорит while(1), поэтому он никогда не заканчивается независимо.

...