我正在编写一个应用程序,它首先从unix管道接收数据,然后提示用户输入.我似乎无法弄清楚为什么在提示用户输入之前管道的输入似乎没有正确关闭.感觉我在这里缺少一些非常基本的东西.
我曾尝试提出了冲洗标准输入所有的例子在这里没有成功.这也似乎有可能相关,但我还没有设法提取任何相关的答案.
#include <stdio.h>
#include <stdlib.h>
#define BUFSZ 1024
int main(void) {
char *buf = calloc(BUFSZ, sizeof(char));
while(fgets(buf, BUFSZ, stdin)) { printf("Pipe input: %s", buf); }
printf("Enter input: ");
fgets(buf, BUFSZ, stdin);
printf("User input: %s", buf);
free(buf);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
用法和输出示例:
$ cat testdata2 | ./a.out
Pipe input: testdata testdata
Pipe input: testdata testdata2
Pipe input: testdata testdata3
Pipe input: testdata testdata4
Pipe input: testdata testdata5
Pipe input: testdata testdata6
Pipe input: testdata testdata7
Enter input: User input: testdata testdata7
$
Run Code Online (Sandbox Code Playgroud)
怎么可能第二个fgets()(用于键盘输入)从不接触缓冲区?
该MCVE已经在OSX和Linux上进行了编译测试,结果相同.
小智 5
如果stdin是管道,那么stdin不是终端.当你到达管道的尽头时,就是这样!那是结束了stdin.你期待某种神奇的转变,其中stdin停止成为管道并开始成为别的东西.不要指望那样.它仍然是管道.并且EOF已经发生.对于管道,EOF是永久性条件.一旦你打了EOF,你将永远不会得到更多.
检查fgets 每次的返回值.你会看到最后一个返回null,因为它在EOF.
想要读取管道stdin并获得键盘输入的程序必须单独打开终端,如FILE *tty = fopen("/dev/tty", "r");