Изменить: это ошибка 1190 в glibc, очевидно, это было сделано специально для совместимости с System V (и Solaris ведет себя точно так же, FreeBSD и NetBSD ведут себя так, как ожидалось).
Обратите внимание, что ваши ожидания верны лишь частично.
Клавиша CTRL-D не является маркером EOF в Unix. Он очищает входной буфер, чтобы программа могла его прочитать. То, что считается EOF в Unix, — это чтение, которое не возвращает ни одного символа, поэтому, если вы очищаете входной буфер в начале строки, это считается EOF. Если вы сбрасываете его после ввода некоторых данных, которые не были сброшены (конец строки сбрасывается автоматически), вам нужно сбросить дважды, чтобы иметь чтение, которое не возвращает никаких символов и будет рассматриваться как EOF.
Теперь, если я выполню эту программу:
#include <stdio.h>
int main()
{
int status;
char tab[200];
while ((status = fscanf(stdin, "%s", tab)) == 1) {
printf("Read %s\n", tab);
printf("status=%d\n", status);
printf("ferror=%d\n", ferror(stdin));
printf("feof=%d\n", feof(stdin));
}
printf("\nOut of loop\nstatus=%d\n", status);
printf("ferror=%d\n", ferror(stdin));
printf("feof=%d\n", feof(stdin));
return 0;
}
и что я нажимаю CTRL-D в начале строки, я получаю ожидаемое поведение:
foo
Read foo
status=1
ferror=0
feof=0
^D
Out of loop
status=-1
ferror=0
feof=1
Если я не закончу строку, а дважды нажму CTRL-D (как я объяснил выше, я ожидаю нажать ее дважды) после foo, мне придется нажать еще один CTRL-D:
./a.out
foo^D^DRead foo
status=1
ferror=0
feof=1
^D
Out of loop
status=-1
ferror=0
feof=1
и я думаю, что это ошибка, scanf
должен был выйти немедленно с результатом EOF, если введен, а feof
равен 1.
person
AProgrammer
schedule
10.11.2013
while (! feof (stdin))
наwhile (1)
. (feof() всегда неверен...) Также: EOF не является символом; вы не можете отправить его, как вы отправляете символ в поток или файл. - person wildplasser   schedule 10.11.2013stdin
является вашим терминалом, условие EOF отсутствует. Трудно добраться до конца файла, когда этот файл не является реальным файлом с конечными данными, а представляет собой клавиатуру (реальную или виртуальную), которая может просто генерировать больше данных в любое время. - person mah   schedule 10.11.2013while(1)
и добавилif (status==EOF) break;
, и в результате мне теперь нужно нажать Ctrl + D три раза - person Tomas Chalupnik   schedule 10.11.2013