2017-01-21 5 views
3

Я изучаю, как вводятся работы в C. Моя самая большая борьба - это понимание поведения EOF в терминале
Во-первых, я использую компилятор Windows и GCC «В случае, если это может помочь»
Во-вторых, я не пытаюсь перенаправить ввод из файла ... мой вопрос о вводе с консоли Windows

Мой вопрос:

Я прочитал, что EOF закрывает входной поток, что вы не можете читать с stdin после EOF ... Это не касается меня! Даже после того, как я вхожу в явном виде Enter-Ctrl-Z-Enter, если я сделать еще GetChar() называют это читает из стандартного ввода ... Пример:
Поведение Stdin и EOF под консолью Windows

int c = 0; 
char str[100]={0}; 

printf("Type in a string with spaces so some chars would remain in Stdin: "); 
//Let's say i type "Hello world!" 
scanf("%s",str); 

while((c=getchar()) != EOF) 
    printf("%c",c); 
//it displays " World!" in console, then i type Enter-^Z-Enter 
//The loop exits so far so good 

printf("Let's just check if we can still read from stdin, type a char: "); 
c = getchar(); //i type the letter 'a' 
printf("\nYou entered: %c\n",c); //It displays 'a'?! 


Кроме того, что-то странное происходит, когда вы вводите^Z в середине строки, любые символы перед тем, как он будет возвращен, но что-либо напечатано после того, как оно исчезнет! Но когда вы проверяете содержимое переменной, оно не равно -1? Вот пример:

int c = 0; 
char str[100]={0}; 

printf("Type in a string with spaces so some chars would remain in Stdin: "); 
//This time i type "Hello wor^Zld!" with ^Z in the middle of "World!" 
scanf("%s",str);  

while((c=getchar()) != EOF) 
    printf("%c",c); 
//it displays " Wor->" in console, with the cursor hanging waiting for input 
/* 
So on the one hand, after ^Z everything disappears, but on the other 
hand it's waiting for input so it's not EOF?! 
*/ 

//In case you're wondering, here too i can call getchar() and read from stdin! 
printf("Let's just check if we can still read from stdin, type a char: "); 
c = getchar(); //i type the letter 'a' 
printf("\nYou entered: %c\n",c); //It also displays 'a'?! 


Поверь мне, я действительно пытаюсь понять, как это работает, но это действительно запутанная для новичка в C ... Так что любая помощь будет принята с благодарностью!

+1

см https://msdn.microsoft.com/sv-se/library/xssktc6e.aspx about eof –

ответ

1

Вы используете Ctrl-Z для сигнала EOF. Ваша программа ведет себя соответственно. Но stdin останется открытым. Вы все еще можете «закрыть» stdin, но только для своей программы. Попробуйте, и вы увидите разницу:

while ((c = getchar()) != EOF) 
     printf("%c", c); 
    fclose(stdin); // <---------- 
    printf("Let's just check if we can still read from stdin, type a char: "); 
    c = getchar(); 
    printf("\nYou entered: %c\n", c); 

Вы не получите «а» больше, вы получите EOF (-1).


Редактировать:

  • EOF является определение макроса в stdio.h, и обычно равен -1
  • Для имитации EOF с помощью терминала ввода, введите последовательность: Enter-Cntrl -Z-Enter в консоли Windows.
  • После сигнала EOF входной поток остается открытым ... Почему? Потому что stdin должен быть всегда открытым. (Можно было бы использовать fclose(stdin), чтобы закрыть поток, но это плохая идея, так как файловые дескрипторы можно легко перепутать.)
  • ^Z не EOF, если вы проверяете его значение, то это 26 (не -1).
  • Typing^Z в любом месте будет промывать после стандартного ввода, что ...
+1

спасибо за ответ. Я знаю fclose(), однако EOF, поскольку сам термин означает, что «End Of File» должен был работать. Он работает для некоторых людей под Linux и основывается на ответах на этот вопрос (http://stackoverflow.com/questions/288062/is-close-fclose-on-stdin-guaranteed-to-be-correct) fclose (stdin) - плохая идея – user7427260

+1

Конечно. Я думал, вы хотите понять, как это работает. :) Кроме того, PLS проверить, как сигналы работают. Когда вы вводите^Z, EOF * сигнализируется *. – Laszlo

+0

ОК будет делать, кстати, когда EOF будет сигнализировать, что произойдет дальше? как я сказал в первом комментарии, поскольку сам термин подразумевает и в соответствии с ответом на этот [вопрос] (http://stackoverflow.com/questions/1622092/problem-with-eof-in-c) не должно быть больше input read ... – user7427260

1

Позвольте мне объяснить: классическое использование этой функции читается из файлов. Каждый файл заканчивается EOF. stdin - «специальный файл», потому что у него нет EOF. Итак, как это работает? Каждый раз, когда вы нажимаете Enter, строка, которую вы набрали, вставлена ​​в буфер stdin. Каждый вызов getchar() считывает одиночный символ из этого буфера. Когда вы вызываете getchar(), и буфер пуст, программа ждет, когда пользователь наберет новую строку, и нажмите Enter. Итак, когда мы получили EOF от stdin? В принципе, никогда. НО пользователь может имитировать EOF по типу Ctrl + Z. Это будет вводить символ EOF, но он не влияет на ничего !. В этом случае это всего лишь символ.

+1

EOF не является символом, это макрос ... для получения дополнительной информации см. [link] (http://stackoverflow.com/questions/12389518/representing-eof-in-c-code) – user7427260

+0

и, честно говоря, ваш ответ не о моем вопросе. Если вы что-то не поняли, пожалуйста, повторите вопрос (BTW, спасибо за ответ :)) – user7427260

+0

Я нахожу этот ответ правильным и достаточно хорошо объясненным, особенно когда говорю, что EOF является особый предмет в консоли. – linuxfan