【发布时间】:2019-04-22 21:00:21
【问题描述】:
自从我上次用 C 编程以来已经有一段时间了,我在使管道工作时遇到了麻烦。 (为了清楚起见,我在 Windows 7 上使用 Cygwin。)特别是,我需要帮助理解以下示例的行为:
/* test.c */
#include <stdio.h>
#include <unistd.h>
int main() {
char c;
//scanf("%c", &c); // this is problematic
int p[2];
pipe(p);
int out = dup(STDOUT_FILENO);
// from now on, implicitly read from and write on pipe
dup2(p[0], STDIN_FILENO);
dup2(p[1], STDOUT_FILENO);
printf("hello");
fflush(stdout);
// restore stdout
dup2(out, STDOUT_FILENO);
// should read from pipe and write on stdout
putchar(getchar());
putchar(getchar());
putchar(getchar());
}
如果我调用:
echo abcde | ./test.exe
我得到以下输出:
hel
但是,如果我取消注释 scanf 调用,我会得到:
bcd
我无法解释。这实际上是一个具有fork/exec 结构的更复杂程序的非常简化版本,该结构开始表现得很糟糕。尽管没有循环,但它以某种方式开始在无限循环中产生无限的孩子。因此,如果规则允许,我可能需要用更具体的使用案例来扩展这个问题。非常感谢。
【问题讨论】:
-
scanf 在您操作文件描述符之前从标准输入读取一堆数据(可能是 4096 或 8192 字节)。
-
好的,但这与管道有什么关系?如果您的意思是
p[0]“开始”与那一堆数据,我应该如何解决它? -
不,p[0] 不以数据开头。数据在 stdio 缓冲区中,第一次调用 getchar 将查看该缓冲区,而无需从管道中读取。
-
现在很清楚了,谢谢。