为什么 Linux(?)-Terminal 不是 "consume" '\n' EOF?

Why does the Linux(?)-Terminal not "consume" '\n' EOF?

根据我的阅读,Linux 终端(在默认设置中)缓冲输入并仅在接收到 EOF'\n' 后才发送输入。

当我循环 c = getchar(); 并检查每个 c 是否为 EOF(结束然后中断)我需要执行 CTRL-D 两次 以停止阅读,因为第一个 EOF 总是被终端消耗(我知道可以将终端更改为原始终端,但也许这有点矫枉过正)。

但是,当我检查 c 是否为 '\n'(它也发送输入)时,它不会被消耗。

示例:

这不是很矛盾吗?或者有什么理由吗?

我想解析包括空格的输入,因此无法检查 '\n' 但检查 EOF - 是否可以不将终端更改为原始终端?

我也尝试过 feof(stdin),但显然这也不起作用:/

您误解了 Ctrl-D 的作用。 Ctrl-D 不会发送 EOF -- 它会将终端缓冲区的当前内容发送到文件描述符,以便在下一个 read 调用时返回。

另一方面,EOF 是当 read 调用 returns 0 个字符时。因此,当终端缓冲区为 empty.

时,ctrl-D 只会导致 EOF

事情不是这样的。 ^D 在当前缓冲的行上发送,因此如果您没有在换行后立即点击它,您的程序将看不到空读取并且不知道输入已结束。所以你需要另一个 ^D 来发送任何东西。但是你的程序永远不会看到 ^D.

实际上你可以用stty来改变终端的EOF字符,例如^N将结束输入;您的程序将 运行 完全相同,因为它不依赖于 EOF 键盘字符的值。

PS。由于您正在尝试编写 C 程序:输入调用 return EOF 当他们尝试读取文件并获得空缓冲区(0 个字符)时。其实EOF并不是你想象的^D,而是-1:选择这个值是因为不是一个字节,而read() 可以合法地 return 任何可能的字节(是的,甚至 '' aka ^D)。这就是为什么 getchar() 的签名说 return 是 int.