C-stdin、unix管道和EOF

C-stdin、unix管道和EOF,c,pipe,c99,C,Pipe,C99,我正在编写一个应用程序,它首先从unix管道接收数据,然后提示用户输入。我似乎无法理解的是,为什么在提示用户输入之前,管道中的输入似乎没有正确关闭。我觉得我错过了一些非常基本的东西 我已经尝试了所有的例子,但都没有成功。似乎也有潜在的相关性,但我还没有找到任何相关的答案 #include <stdio.h> #include <stdlib.h> #define BUFSZ 1024 int main(void) { char *buf = calloc(B

我正在编写一个应用程序,它首先从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;
}
第二个fgets()(用于键盘输入)怎么可能从未接触过缓冲区


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

如果
stdin
是管道,则
stdin
不是终端。当你到了管道的尽头,就这样了!这就是stdin的结尾。你期待着某种神奇的转变,
stdin
不再是管道,而是开始成为其他东西。别指望那样。还是管子。发生了EOF。对于管道,EOF是一种永久性条件。一旦你达到EOF,你就再也得不到任何东西了

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


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

如果
stdin
是管道,则
stdin
不是终端。当你到了管道的尽头,就这样了!这就是stdin的结尾。你期待着某种神奇的转变,
stdin
不再是管道,而是开始成为其他东西。别指望那样。还是管子。发生了EOF。对于管道,EOF是一种永久性条件。一旦你达到EOF,你就再也得不到任何东西了

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


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

你应该
calloc()
BUFSZ+1,这样你就有足够的空间来存放
\0
,如果你在一行中读取足够长的内容来填充缓冲区的话。你的问题不在于
stdin
没有关闭(它会关闭,因为
fgets
返回
NULL
),但它不会重新打开供用户输入。@ChrisTurner
fgets
允许这样做:您只需告诉它实际的缓冲区大小。@Kninnug这确实是问题所在。非常感谢。你应该
calloc()
BUFSZ+1,这样你就有足够的空间来存放
\0
,如果你在一行中读取足够长的内容来填充缓冲区的话。你的问题不是
stdin
没有关闭(它会关闭,因为
fgets
返回
NULL
),但它不会重新打开供用户输入。@ChrisTurner
fgets
允许这样做:您只需告诉它实际的缓冲区大小。@Kninnug这确实是问题所在。非常感谢。啊,是的,这似乎确实是解决办法。我知道我错过了一些基本的东西。非常感谢。啊,是的,这似乎确实是解决办法。我知道我错过了一些基本的东西。非常感谢。
$ 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
$