与缓冲区和EOF和getchar混淆

时间:2015-03-13 22:37:35

标签: c buffer eof getchar

我使用getchar()putchar()以及'\n'和EOF(在Visual Studio中)测试了很多情况,以更好地了解缓冲和getchar的工作原理。

如果我的代码

int c;
printf("Enter character\n");
/* 1 - number for explaining steps */
c = getchar();
putchar(c);

/* 2 */
c = getchar();
putchar(c);

printf("hi");

在此代码中,如果我输入字符a并按Enter键,则会显示

 a
 hi

这意味着当我按下输入时,'\n'也将保存在缓冲区中,然后缓冲区中的第一项(a)转到第一个c=getchar()并且a已打印;然后缓冲区中的第二项(\n)转到第二项 c=getchar()并打印新行。

我得出结论,'\n'保存在缓冲区中,这不是命令在按Enter键时转到新行的结果,因为我测试了另一个代码:

while ((c = getchar()) != '\n')
    putchar(c);
printf("hi");

在此代码中,当我输入a并按Enter键时,它会打印ahi而新行不会打印,这意味着当a传递给getchar()时,{{ 1}}打印它然后当putchar()获得getchar()时,循环终止并且循环内的'\n'不打印新行,因此命令不是新行的原因

现在我想测试另一个代码:

putchar()

如果我传递它 int c; while ((c = getchar()) != EOF) putchar(c); printf("hi"); return 0; 和EOF信号(在我的系统中^ Z( Ctrl + Z )),它将显示abc。如果我们像前面的代码一样看它: abc->应该保存在缓冲区中,并且abc-1(or every thing else shows eof)'\n'首先转到第一个getchar(第一次循环工作),a传递给第二个getchar,然后b传递给第三个 - 然后c应该传递给-1 并且它违反条件并且循环应该终止。

然而,它打印c=getchar()并循环继续,并且不打印新行(缓冲区中的最后一项)。 相反,当-> ctr +z从缓冲区读取EOF符号时,循环终止并打印新行,以便为什么打印新行? 它读取EOF,它不应该读取缓冲区中的任何其他内容 在这种情况下。

1 个答案:

答案 0 :(得分:2)

您的输入首先读取a然后第一个示例中的换行符的概述基本上是正确的。就getchar()而言,换行是一个完全正常的角色;的确,没有异常的人物。 getchar()可以返回任何适合char的8位值,加上一个额外的值,称为EOF。这就是为什么它的返回值必须存储在int中,正如您所做的那样。

当基础read()系统调用返回可读取的0字节时,或者出现错误时,标准I / O函数返回EOF。

在Windows上键入abc Control-Z (您在Unix上键入 Control-D ),然后:

  1. 终端驱动程序使当前位于其缓冲区(abc)中的字符可用于read()系统调用。
  2. read()系统调用使用这些字符填充标准I / O缓冲区。
  3. 连续getchar()次来电回复abc
  4. 下一个getchar()等待更多输入。
  5. 这不是EOF;它只是将线上的字符刷新到程序中。要获得EOF的效果,您必须在abc之后连续两次输入 Control-Z 。第一个会刷新abc;第二个将生成read()个0字节,表示EOF。

    当按下换行符(Enter)时,终端驱动程序也可以输入。如果在输入Enter后立即键入 Control-Z ,则所有待处理字符的零都将从终端发送到程序,因此read()返回0,因此标准I / O包报告EOF。

    请注意,在您按Enter或EOF指示之前,您可以使用退格键和其他编辑选项编辑行中的数据,包括删除所有数据。一旦您点击输入或EOF指示,您就无法再编辑read()可用的数据。

    类似的行为发生在Unix上;您键入EOF指示两次以终止输入中线;一次在一行开头终止输入。

    Stack Overflow上有很多相关问题,包括以下问题: