2013-11-10 2 views
1

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

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

заменить 'while (! feof (stdin)) 'by' while (1) '. (feof() не всегда _) ... Также: EOF не является _character_; вы не можете _send_ это как вы посылаете символ в поток или файл. – wildplasser

+0

Если 'stdin' - ваш терминал, условия EOF отсутствуют. Трудно добраться до конца файла, когда этот файл не является реальным файлом с конечными данными, а скорее представляет собой клавиатуру (реальную или виртуальную), которая может просто генерировать больше данных в любое время. – mah

+0

Я заменил его на 'while (1)' и добавил 'if (status == EOF) break;' и результат в том, что я должен нажать Ctrl + D три раза сейчас –

ответ

3

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.

Смежные вопросы