作为Linux系统编程练习我编写了自己的tree命令版本,它是从stdin读取并仅使用基本的read()和write()C库函数写入stdout。我已经这样做了,当输入星号(*)时,程序终止。我设法让它正常工作,我的问题是我真的理解为什么它的工作方式。令我困惑的是缓冲区。首先,这是有问题的代码部分:
char buf[1];
...
do {
read(STDIN_FILENO, buf, 1);
if( buf[0] == '*') break;
write(STDOUT_FILENO, buf, 1);
} while( buf[0] != '*');
...
我的想法是从char读取stdin char,从而将char存储在buf中,检查它是否为星号,然后将char从buf写入stdout。
行为如下:我输入任意数量的字符串,按ENTER键,该字符串输出到stdout,此时我可以键入一个新的字符串。如果字符串以星号结尾,则输出字符串直到星号,然后程序终止。
我的问题是:
1)buf只能包含一个char。怎么可能在输入任何数量的字符时按下ENTER键将所有字符输出到标准输出?我希望一次输出一个char,或者只输出最后一个char。 one-char缓冲区如何存储所有这些字符?或者创建了多个one-char缓冲区?由谁?
2)提示字符串输出的换行符有什么特别之处?为什么它不仅仅是字符串中的另一个字符?这只是函数read()中定义的问题吗?
感谢您帮助理解缓冲区的工作原理!
答案 0 :(得分:1)
在控制台输入输入时,输入字符不会立即输入stdin
。按 Enter 按钮后,您输入的整行(包括换行符)将在运行时环境中输入到标准输入。
答案 1 :(得分:1)
这是基于IO调用的方式 - 读取和写入将适用于大多数操作系统。
您只读取1个字节,因此在您输入时,内容将由io缓冲区(不是您的缓冲区)保存,直到您的循环读取它为止。因为你没有睡觉,所以它会阅读,或者等待阅读的速度超过人类输入的速度。
同样如R Sahu建议的那样 - 输入缓冲区可能无法显示给您的程序,直到您在键入的控制台上按Enter键。这取决于控制台及其配置 - 但大多数将缓冲行并等待输入。如果你输入标准输入,那将会有所不同。
要读取的最后一个参数“1”是指示它在此处读取一个字节的内容。
第二部分是您的输出也是缓冲的,并且控制台输出缓冲区通常使用换行来刷新和显示该行。在那种情况下,它会被您的代码写入该输出缓冲区。如果您不想要这种行为,那么写入后的fflush
调用应该逐个字符地输出。