Как завершить сканирование, введя только один EOF

Я решаю эту проблему. Я использую цикл while для сканирования строки чисел, и мне нужно прекратить сканирование и продолжить работу с остальной частью моей программы. Я просто не могу понять, как очистить стандартный ввод или сделать что-нибудь, чтобы не нажать Ctrl+D дважды. Мне просто нужно отправить EOF только один раз, чтобы завершить цикл.

while (! feof (stdin))
    {status=scanf ("%d", &array[i]);
    if ( (status != 1 && status != EOF) )
    {       printf("\nWrong input.\n");
            return 1;}
    i++;}

1 ответ

Редактировать: это ошибка 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.

Другие вопросы по тегам