Edit: it's bug 1190 on 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
Если я не» t завершите линию, но дважды нажмите 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.
заменить 'while (! feof (stdin)) 'by' while (1) '. (feof() не всегда _) ... Также: EOF не является _character_; вы не можете _send_ это как вы посылаете символ в поток или файл. – wildplasser
Если 'stdin' - ваш терминал, условия EOF отсутствуют. Трудно добраться до конца файла, когда этот файл не является реальным файлом с конечными данными, а скорее представляет собой клавиатуру (реальную или виртуальную), которая может просто генерировать больше данных в любое время. – mah
Я заменил его на 'while (1)' и добавил 'if (status == EOF) break;' и результат в том, что я должен нажать Ctrl + D три раза сейчас –