C - stdin, unix pipeline and EOF



我正在编写一个应用程序,该应用程序首先从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;
}

示例用法和输出:

$ 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
$

第二个 fgets(((用于键盘输入(怎么可能永远不会接触缓冲区?

此MCVE已在OSX和Linux上编译,结果相同。

如果stdin是管道,则stdin不是终端。当你到达管道的尽头时,就是这样!stdin到此结束.你期待某种神奇的转变,stdin不再是管道,而是开始成为别的东西。不要指望。它仍然是管道。EOF已经发生。对于管道,EOF是永久性条件。一旦你达到了EOF,你就再也得不到任何东西了。

每次都检查 fgets 的返回值。您将看到最后一个返回 null,因为它位于 EOF。

想要读取管道stdin并获得键盘输入的程序必须单独打开终端,如FILE *tty = fopen("/dev/tty", "r");

最新更新