【问题标题】:Use cat output in another program with pipe in C在另一个程序中使用 cat 输出与 C 中的管道
【发布时间】:2014-09-19 02:05:25
【问题描述】:

我想运行:cat somefile | program > UNIX 系统中的输出文本。

我看过很多东西,比如管道、使​​用popen、dup2等;我迷路了。

基本代码应该是:

  • 使用program 读取cat 产生的任何输出并执行一些魔术,然后将数据输出到 outputText。

有什么建议吗?

附言 这些文件是二进制文件。

更新:

我发现这段代码可以与上面规定的命令一起使用......但是 它会做我不想要的事情。

  1. 如何摆脱sort?我尝试擦除内容,但随后出现错误并且程序无法运行。
  2. cat 以二进制方式读取数据
  3. 以二进制形式向终端输出数据

有什么建议吗?

int main(void)
{
    pid_t p;
    int status;
    int fds[2];
    FILE *writeToChild;
    char word[50];

    if (pipe(fds) == -1)
    {
        perror("Error creating pipes");
        exit(EXIT_FAILURE);
    }

    switch (p = fork())
    {
        case 0: //this is the child process
            close(fds[1]); //close the write end of the pipe
            dup2(fds[0], 0);
            close(fds[0]);
            execl("/usr/bin/sort", "sort", (char *) 0);
            fprintf(stderr, "Failed to exec sort\n");
            exit(EXIT_FAILURE);

        case -1: //failure to fork case
            perror("Could not create child");
            exit(EXIT_FAILURE);

        default: //this is the parent process
            close(fds[0]); //close the read end of the pipe
            writeToChild = fdopen(fds[1], "w");
            break;
    }

    if (writeToChild != 0)
    {
        while (fscanf(stdin, "%49s", word) != EOF)
        {
            //the below isn't being printed.  Why?
            fprintf(writeToChild, "%s end of sentence\n", word);
        }
        fclose(writeToChild);
    }

    wait(&status);

    return 0;
}

【问题讨论】:

  • 当您可以将programstdin 设置为somefile 时,为什么还要使用cat 来输入它?即program < somefile > outputText
  • 不幸的是,我的任务指定我必须这样做。
  • 并且cat读取的文件是二进制的,如果可能的话输出也应该是二进制的。
  • 我需要2个文件吗?一个文件做管道?我注意到许多程序调用 exec(),它们在其中调用特定文件,在我的情况下是程序?所以 pipe.c 会调用 program.c 并以某种方式从 cat 中获取标准输出并将其放入 program.c???
  • 如果你,如你所说,应该(家庭作业?)以cat somefile | program > output 运行程序,那么你就走错了路。像这样运行命令使 shell pipe 成为 cat 的输出到 program 的输入。这与在程序中设置管道不同。 en.wikipedia.org/wiki/Redirection_(computing)#Piping

标签: c unix pipe cat piping


【解决方案1】:

这是我的建议,因为你想读写二进制文件:

#include <stdio.h>

int main (void) {
    if (!freopen(NULL, "rb", stdin)) {
        return 1;
    }
    if (!freopen(NULL, "wb", stdout)) {
        return 1;
    }

    char buf[4];
    while (!feof(stdin)) {
        size_t numbytes = fread(buf, 1, 4, stdin);

        // Do something with the bytes here...

        fwrite(buf, 1, numbytes, stdout);
    }
}

【讨论】:

  • 这就是我刚刚所做的 :).. 花了一段时间才弄清楚如何使标准输出输出二进制。希望我在 20 分钟前看过这个。
  • EOF 检查出现故障。您应该在fread() 之后但在fwrite() 之前检查feof()。或者直接使用fread()的返回值。
  • @FatalError 来自fread 手册页:“如果发生错误,或者到达文件末尾,则返回值是一个短项目计数(或零)。” IE。 numbytes 保存实际读取的字节数,即使已达到 EOF。这些字节需要被写入。
  • @Henrik:+1 是的,现在我更仔细地查看您的代码是正确的。如果读取未能返回任何数据,它将以 0 字节调用 fwrite(),因此它实际上不会写入 buf 中的任何内容。
【解决方案2】:

为了能够读取cat 的输出(标准输出),您无需传输我发现的任何内容,感谢你们!我被管道弄得一头雾水……

所以如果你运行“cat somefile | program”,其中 somefile 包含二进制数据... 您只会看到 somefile 包含的任何内容,并在终端上重新打印。

谢谢!现在我可以写完我的program了。

/*program.c*/

int main()
{
    int i, num;

    unsigned char block[2];

    while ((num = fread(block, 1, 2, stdin)) == 2)
    {
        for(i = 0; i < 2; i++)
        {
            printf("%02x", block[i]);
        }
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    • 2010-11-20
    • 1970-01-01
    • 2021-06-14
    • 1970-01-01
    相关资源
    最近更新 更多