#include <stdio.h>
int main()
{
int c;
while((c=getchar())!=EOF)
putchar(c);
return 0;
}
在我有限地接触C的情况下,只要C!= EOF,就会执行while条件,该条件本质上将打印c,然后等待下一个字符并尝试检查是否违反条件。因此,对于我们输入的每个字符,将执行putchar。 但是,当我运行可执行文件时,似乎发生的事情是只有当我按下换行键(Enter)时,print语句才能工作,并且它具有某种类型的缓冲区,可以在输入中打印整行。 我在代码中看不到任何将保留字符的缓冲区,直到按了新行为止,那么这里正在做什么? 这些字符存储在哪里,直到按下新行?
答案 0 :(得分:2)
从这样的控制台读取时,您的程序实际上根本没有收到任何输入,除非您按Enter键,然后它会立即读取并处理整行。
您的程序不知道这些字符甚至在您按Enter键之前就存在,此时它们将被发送到stdin缓冲区。从这里开始,循环将读取并打印每个字符(包括新行),直到缓冲区为空(这意味着它将等待更多输入)或到达文件末尾为止。
答案 1 :(得分:1)
在读取数据和写入数据时发生缓冲。
stdin
和stdout
可以分别缓冲字符,行或 。
在通常情况下,两者都是 line 缓冲。
在打 Enter (getchar()
)之前,不会向'\n'
提供输入。 (您可以退格输入吗?)直到输出'\n'
时才显示输出。
答案 2 :(得分:1)
getchar()
和putchar()
函数是stdio
程序包的一部分,该程序包用于缓冲输入/输出。
这意味着,尽管您实际请求的字符数(仅在您的情况下为一个),缓冲机制仍使字符在缓冲区中等待,直到整个缓冲区(或{{1})为一行来自tty设备)填充。
这里发生的事情是,首先stdin
要求完全填充缓冲区,并且只用您键入的输入行部分填充。之后,所有getchar()
调用都使用单个字符从缓冲区开始,直到再次变空为止,然后请求另一个完整的缓冲区。
使单字符处理成为一种有效的处理方式。输出也会发生这种情况。 getchar()
函数只会填充缓冲区,直到缓冲区完全填满(或者,如果您的输出通道连接到tty设备,直到您请求输出putchar()
字符)为止;完整的缓冲区输出到文件/设备。
此外,各种unix的终端驱动程序都可以在行模式下工作,这意味着在您按下【{{1}】】键之前,您什么也不会发送到程序。这将允许您通过使用擦除键(退格键)和/或取消键(Cntrl-U)来更正键控上的错误。这是在Windows控制台应用程序中模拟的,因此您可能需要使输出设备进入原始模式,然后才能以基于字符的方式进行输入。
如果要使程序一次读取一个字符,则需要绕过stdio的缓冲区(通过\n
函数调用,或使用<ENTER>
系统调用来读取一个字符) ,可以通过以下方式完成:
setbuf(NULL)
),然后将终端驱动程序置于原始模式(通过read(2)
和char c;
int res = read(0, &c, 1);
if (res < 0) { /* error */
...
} else if (res == 0) { /* EOF in input */
...
} else { /* 1, as you requested only one char */
... /* one character was read. */
}
调用,请参阅tcsetattr()
手册页以获取有关执行此操作的详细信息),然后再进行实际阅读。在这种情况下,必须在终止程序之前将终端状态返回到线路模式,否则会遇到麻烦。