【问题标题】:In C how to read the output of a process and write it in the input of another?在 C 中如何读取一个进程的输出并将其写入另一个进程的输入?
【发布时间】:2022-01-15 10:24:11
【问题描述】:

您好,我有一个 C 程序,基本上假设它模拟 linux 中的管道函数并写入在 .txt 文件中读取的字节数,所以 ./a.out cat test : grep -v le : wc -l

我要解决的问题是

既然我知道每个进程返回的数量不同,为什么文件中写入的字节数相同?

这段代码在父进程中执行,并尝试使用读取系统调用计算每个输出的字节数,并将输出写入下一个进程的写入系统调用,以便下一个进程可以将输出用作他的意见。

假设我有这些管道a | b | c 此代码将读取a 的输出并将其写入b,以便b 可以将其用作输入等等。

 for (int i = 1; i < processes-1; i++) {
       
       close(apipe[i][1]);
       char str[4096];
       int count=0;
       int nbChar=0;
       
       while(1){
                count=read(apipe[i][0],str,sizeof(str));
                nbChar+=count;
                if(count==-1){
                    if (errno == EINTR) {
                        continue;
                    } else {
                        perror("read");
                        exit(1);
                    }
                }else if(count==0)break;
      }
      char *leInput=(char*)malloc(nbChar*sizeof(char));
      strncpy(leInput,str,nbChar);
      if(i>0){
        fprintf(fp, "%d : %d \n ", i,nbChar);  
      }
      close(apipe[i][0]); 
      write(apipe[i+1][1], leInput, nbChar);
      
     
  }

【问题讨论】:

  • 每次调用read() 时,您都会写入str 的开头,通过循环覆盖您上次读取的内容。
  • 所以没有nbChar 字符可以复制到leInput
  • 但是我在每个进程之后都重置了循环,所以下一个进程不能访问新的 str 吗?
  • 我说的是while 循环。

标签: c linux pipe dup


【解决方案1】:

每次通过while(1) 循环,您都会读入str 的开头,而不是您在上一次迭代中中断的位置。因此,您正在用下一次读取覆盖上一次读取。

您应该每次通过循环增量复制到leInput。然后,您可以使用realloc() 来扩大它以适应新的输入,并且您可以使用leInput + nbChar 在您上次完成的地方之后复制。

for (int i = 1; i < processes-1; i++) {
       
    close(apipe[i][1]);
    int nbChar=0;
    char *leInput = NULL;
       
    while(1){
        int count=0;
        char str[4096];
        count=read(apipe[i][0],str,sizeof(str));
        if(count==-1){
            if (errno == EINTR) {
                continue;
            } else {
                perror("read");
                exit(1);
            }
        } else if(count==0) {
            break;
        }
        leInput = realloc((nbChar + count)*sizeof(char));
        memcpy(leInput + nbChar, str, count);
        nbChar += count;
    }
    if(i>0){
        fprintf(fp, "%d : %d \n ", i,nbChar);  
    }
    close(apipe[i][0]); 
    write(apipe[i+1][1], leInput, nbChar);
}

或者,您可以只写入内部循环中的下一个管道,而不将所有内容收集到leInput

for (int i = 1; i < processes-1; i++) {
    int nbChar = 0;

    close(apipe[i][1]);
       
    while(1){
        int count=0;
        char str[4096];
        count=read(apipe[i][0],str,sizeof(str));
        if(count==-1){
            if (errno == EINTR) {
                continue;
            } else {
                perror("read");
                exit(1);
            }
        } else if(count==0) {
            break;
        }
        write(apipe[i+1][1], str, count);
        nbChar += count;
    }
    if(i>0){
        fprintf(fp, "%d : %d \n ", i,nbChar);  
    }
    close(apipe[i][0]); 
    close(apipe[i+1][1])
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-28
    • 1970-01-01
    • 1970-01-01
    • 2011-08-28
    • 2015-12-29
    • 2010-10-02
    • 2014-07-21
    • 1970-01-01
    相关资源
    最近更新 更多