如何在C语言中读取管道内容?

9

我希望能够做到这一点:

$ echo "hello world" | ./my-c-program
piped input: >>hello world<<

我知道应该使用isatty函数来检测stdin是否为tty。如果不是tty,我想读取管道中的内容 - 在上面的例子中,这是字符串hello world
在C语言中,推荐的方法是什么?
以下是我目前得到的:
#include <stdio.h>
#include <unistd.h>

int main(int argc, char* argv[]) {

  if (!isatty(fileno(stdin))) {
    int i = 0;
    char pipe[65536];
    while(-1 != (pipe[i++] = getchar()));
    fprintf(stdout, "piped content: >>%s<<\n", pipe);
  }

}

我使用以下内容进行了编译:

gcc -o my-c-program my-c-program.c

它“几乎”工作了,但似乎总是在管道内容字符串的末尾添加一个U+FFFD替换字符和一个换行符(我理解换行符)。为什么会出现这种情况,如何避免这个问题?

echo "hello world" | ./my-c-program
piped content: >>hello world
�<<

免责声明:我对 C 语言毫无经验。请对我宽容一些。


@H2CO3 你为什么删除了你的答案?它是唯一解释正在发生的事情的答案。或者它是不正确的吗? - Mathias Bynens
1个回答

12

出现替换符是因为您忘记对字符串进行NUL终止。

换行符存在是因为默认情况下,echo在其输出末尾插入'\n'

如果您不想插入'\n',请使用以下命令:

echo -n "test" | ./my-c-program

并且要删除错误的字符插入

pipe[i-1] = '\0';

在打印文本之前。

请注意,您需要使用i-1作为空字符,因为您实现了循环测试的方式。在您的代码中,i在最后一个字符之后增加了一次。


pipe[i-1] = '\0'pipe[i-1] = 0; 似乎都能够正常工作。谢谢! - Mathias Bynens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接