混淆缓冲区和 EOF 和 getchar

confusing with buffer and EOF and 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 并按回车键时,它会打印 ahi 并且不会打印新行,这意味着当 a 传递给 getchar() 时, putchar() 然后当 getchar() 得到 '\n' 时打印它,循环终止并且循环内的 putchar() 不打印新行所以命令不是新行。

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

  int c;
  while ((c = getchar()) != EOF)
    putchar(c);
  printf("hi");
  return 0;

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

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

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

当底层 read() 系统调用 return 0 个字节可供读取时,标准 I/O 函数 return EOF — 或者出现错误时。

当您在 Windows 上键入 abcControl-Z 时(您将键入 Control-D而不是在 Unix 上),然后:

  1. 终端驱动程序使当前在其缓冲区 (abc) 中的字符可用于 read() 系统调用。
  2. read() 系统调用使用这些字符填充标准 I/O 缓冲区。
  3. 连续的 getchar() 调用 return abc
  4. 下一个 getchar() 等待更多输入。

这不是 EOF;它只是将行中的字符刷新到程序中。要获得 EOF 的效果,您必须在 abc 之后连续输入两次 Control-Z。第一个会刷新 abc;第二个将生成 0 字节的 read(),表示 EOF。

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

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

可用的数据

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

Stack Overflow 上有很多相关问题,包括这些:

  • Canonical vs non-canonical terminal input
  • while ((c = getc(file)) != EOF) loop won't stop executing
  • Control-D didn't stop the while (getchar() != EOF) loop
  • How to stimulate EOF without preceding newline in C?
  • read() from stdin doesn't ignore newline