Одна из проблем с scanf
и всеми отформатированными функциями ввода заключается в том, что терминалы, как правило, работают в режиме линии или режиме приготовления , а API предназначен для режима raw , Другими словами, реализации scanf
обычно не возвращаются, пока не встретится перевод строки. Вход буферизуется, и будущие вызовы scanf
будут использовать буферизованную строку. Рассмотрим следующую простую программу:
#include <stdio.h>
int main() {
int a_number;
printf("Enter a number: ");
fflush(stdout);
while (scanf("%d", &a_number) != EOF) {
printf("you entered %d\n", a_number);
printf("Enter another number: ");
fflush(stdout);
}
return 0;
}
Вы можете ввести несколько цифр перед нажатием return . Вот пример запуска этой программы.
bash$ gcc foo.c
bash$ ./a.out
Enter a number: 1 2 3 4 5 6 7 8 9 10<Return>
you entered 1
Enter another number: you entered 2
Enter another number: you entered 3
Enter another number: you entered 4
Enter another number: you entered 5
Enter another number: you entered 6
Enter another number: you entered 7
Enter another number: you entered 8
Enter another number: you entered 9
Enter another number: you entered 10
Enter another number: <Ctrl+D>bash$
bash$
Каждый вызов scanf
читает один номер из входного потока, но первый вызов не возвращался, пока я не нажал return . Оставшиеся вызовы возвращались немедленно, без блокировки для дополнительного ввода, поскольку входной поток был буферизован, и он мог прочитать другое целое число из потока.
Альтернативой этому является использование fgets
и одновременная обработка целых строк данных или интерфейс терминала для отключения «обработки канонического ввода» . Большинство людей используют fgets
, поскольку раздел интерфейса терминала POSIX не реализован в Windows.