我有一个带读取功能的简单C程序,我不理解输出。
//code1.c
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main()
{
int r;
char c; // In C, char values are stored in 1 byte
r = read ( 0, &c, 1);
// DOC:
//ssize_t read (int filedes, void *buffer, size_t size)
//The read function reads up to size bytes from the file with descriptor filedes, storing the results in the buffer.
//The return value is the number of bytes actually read.
// Here:
// filedes is 0, which is stdin from <stdio.h>
// *buffer is &c : address in memory of char c
// size is 1 meaning it will read only 1 byte
printf ("r = %d\n", r);
return 0;
}
以下是结果的屏幕截图:
我按照上面的说明运行了这个程序2次,然后键入&#34; a&#34;第一次尝试和&#34; aecho hi&#34;第二次尝试。
我如何尝试解释结果:
read
时,它会看到stdin已关闭并打开它(从我的角度来看,为什么?它应该只读它。我不知道为什么打开它)。read
优先处理stdin并读取&#34; aecho hi&#34;的第一个字节。 :&#34; a&#34;。read
已使用printf处理了1个字节的确认。read
删除。这都是假设的,非常模糊。任何有助于了解正在发生的事情的人都会非常欢迎。
答案 0 :(得分:2)
当您在终端模拟器上键入时,它会将您的击键写入&#34;文件&#34;,在这种情况下是一个内存缓冲区,由于文件系统,它看起来就像任何其他可能的文件一样在磁盘上。
每个进程都从其父进程继承3个打开的文件句柄。我们感兴趣的是其中一个,标准输入。终端仿真器执行的程序(此处为bash
)作为标准输入给出了第一段中描述的内存缓冲区。
a.out
,当由bash
运行时,也会收到与其标准输入相同的文件。请记住这一点:bash
和a.out
正在读取已经打开的文件。
运行a.out
后,其read
阻止,因为其标准输入为空。键入aecho hi<enter>
时,终端会将这些字符写入缓冲区(<enter>
成为单个换行符)。 a.out
仅请求一个字符,因此它会获得a
并将剩余的字符留在文件中。 (或者更准确地说,在读取e
之后,文件指针仍然指向a
。)
a.out
完成后,bash
会尝试从同一个文件中读取。通常,文件为空(即文件指针位于文件末尾),因此bash
阻塞等待另一个命令。但是,在这种情况下,已有输入:echo hi\n
。 bash
现在读取此内容就像在 a.out
完成后输入一样。
答案 1 :(得分:1)
检查this。正如alk所说,stdin和stdout已经在程序中打开了。输入后,您必须了解:
aecho hi
并点击返回stdin
缓冲区中填充了所有这些字母(和空格) - 并且只要您不刷新它就会继续。当程序退出时,stdin缓冲区仍然已满,并且终端通过回显stdin
自动处理对stdout
的写入 - 这就是你最后看到的 - 你的shell读取{ {1}}。
现在正如你所指出的那样,你的代码“按回车”可以这么说 - 在第一次执行时添加一个空的shell行,在第二次执行stdin
。但是你必须记住,你按了返回,所以“\ n”在缓冲区中!明确地说,你实际输入了:
echo hi
程序退出后,shell会读取缓冲区中剩余的字符,包括返回,这就是你所看到的!