如何使用read将输出管道传输到C中的另一个程序

时间:2016-07-03 18:39:22

标签: c

我正在尝试阅读程序A中程序B打印的信息。如何使用A将数据从B传递到read()

A

的代码
#include <stdio.h>

int main(int argc, char **argv)
{
    int i, j;
    char    instruc_list[11][3] = {"sa", "sb", "ss", "pa", "pb",
"ra", "rb", "rr", "rra", "rrb", "rrr"};

    i = 0;
    while (i < 11)
    {
        j = 0;
        while (j < 3)
        {
            printf("%c", instruc_list[i][j]);
            j++;
        }
        i++;
        printf("\n");
    }
    return (0);
}

B

的代码
int main()
{
    char buf[4];
    while ((read(0,buf, 4)))
    {
        printf("%s", buf);
    }
    printf("\n");
    return 0;
}

当我运行这两个程序时,我得到以下结果。 enter image description here

3 个答案:

答案 0 :(得分:1)

使用popen()中定义的pclose()stdio.h函数在程序之间管道输出。

以下是一个示例程序,介绍如何在程序中打印ls shell命令的输出,取自link

FILE *fp;
int status;
char path[PATH_MAX];


fp = popen("ls *", "r");
if (fp == NULL)
    /* Handle error */;


while (fgets(path, PATH_MAX, fp) != NULL)
    printf("%s", path);


status = pclose(fp);
if (status == -1) {
    /* Error reported by pclose() */
    ...
} else {
    /* Use macros described under wait() to inspect `status' in order
       to determine success/failure of command executed by popen() */
    ...
}

对于您的情况,您可以致电popen("./A", "r");

答案 1 :(得分:0)

您可以使用popen()从程序B中读取程序A的输出。 编译第一个程序:

gcc a.c -o a

在程序B中:

#include <stdio.h>

int main(void)
{
    char buf[4];
    FILE *fp;

    fp = popen("./a", "r");
    while( !feof(fp)) {
        fscanf(fp, "%s", buf);
        printf("%s\n", buf);
    }
    return 0;
    pclose(fp);
}

现在编译并执行程序B:

gcc b.c -o b

me@linux:$ ./b

我得到的输出是:

sa
sb
ss
pa
pb
ra
rb
rr
rra
rrb
rrr
rrr

答案 2 :(得分:0)

在程序A中,您没有为3个字母的字符串编写空终止符...而在程序B中,您没有在读取的字符后添加空字符(并且没有初始化buf,所以它可能不包含一个)。这就是为什么你在你读的3个字母的字符串之间得到垃圾... printf()继续读你读过的字符,因为它还没有找到null。

另请注意,read()可以返回-1表示错误,对于while循环仍然会测试为true。你应该至少检查read()是否返回大于0(而不仅仅是非零),如果没有进行更全面的错误处理。

因此,通过一些更改来解决这些问题,程序B可能会变为:

int main()
{
    char buf[4];

    int ret; // ** for the return from read()

    while ((ret = read(0,buf, 4)) > 0) // ** read >0 (no error, and bytes read)
    {
        fwrite(buf, 1, ret, stdout); // ** write the number of chars
                                     //    you read to stdout
    }
    printf("\n");
    return 0;
}

对于程序A,现在它为2个字母和3个字母的字符串写入3个字符 - 这意味着它包含2个字母字符串的空字符,但不包括3个字母的字符串。通过对上面的程序B的更改,您根本不需要编写空字符...因此您可以更改:

    while (j < 3)

为:

    while (j < 3 && instruc_list[i][j] != 0)

在达到空字符时停止(尽管使用printf()调用仅写一个char仍然效率低下 - 或许putchar(instruc_list[i][j]);会更好。或者,您可以用以下内容替换内部while循环:

    fputs(instruc_list[i], stdout);

...然后将instruc_list[i]中的字符串写入但不包括null char,并将instruc_list[11][3]更改为instruc_list[11][4],以便它具有null char的空间来自初始化列表中的3个字母的字符串文字。