Windows 控制台下的标准输入和 EOF 行为

Stdin and EOF Behaviour under Windows console

我正在学习 C 中输入的工作原理。我最大的困难是理解终端中的 EOF 行为
首先,我使用 Windows 和 GCC 编译器 "In case this might help"
其次,我不是要重定向来自文件的输入...我的问题是关于来自 Windows console

的输入 我的问题:

我读到 EOF 关闭了输入流,在 EOF 之后你不能从标准输入读取...这对我来说不是这种情况!即使在我明确输入 Enter-Ctrl-Z-Enter 之后,如果我执行另一个 getchar() 调用,它也会从标准输入中读取...例如:

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 语言的初学者来说,它真的很令人困惑......因此,我们将不胜感激任何帮助!

我来解释一下:这个函数的经典用法是从文件中读取。每个文件都以 EOF 结尾。 stdin 是 "special file",因为它没有 EOF。那么它是如何工作的呢?每次您按下 Enter,您输入的字符串就会插入到标准输入缓冲区中。每次调用 getchar() 都会从此缓冲区读取单个字符。当您调用 getchar() 并且缓冲区为空时,程序会等待用户键入新字符串,然后按下 Enter。 那么,我们什么时候从 stdin 得到 EOF?基本上,从来没有。但是用户可以通过键入 Ctrl+Z 来模拟 EOF。这将进入 EOF 字符,但它没有任何作用!。在本例中,它只是一个字符。

您使用 Ctrl-Z 发出 EOF 信号。您的程序会相应地运行。但标准输入将保持打开状态。您仍然可以 'close' 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);

你不会再得到 'a',你会得到 EOF (-1)。


编辑:

  • EOF是stdio.h中的宏定义,一般等于-1
  • 要通过终端输入模拟 EOF,请在 Windows 控制台中键入序列:Enter-Cntrl-Z-Enter。
  • 在 EOF 信号之后,输入流保持打开状态...为什么?因为 stdin 应该总是打开的。 (可以使用 fclose(stdin) 关闭流,但这是个坏主意,因为文件句柄很容易搞乱。)
  • ^Z 不是 EOF,如果你检查它的值,它是 26(不是 -1)。
  • 在任何地方输入 ^Z 之后都会刷新标准输入...