将C程序中的stdin重定向到另一个进程

时间:2010-04-21 03:47:41

标签: c unix stdin

我有一个C程序,我想让它用tr过滤所有输入。所以,我想启动tr作为子进程,将我的stdin重定向到它,然后捕获tr的stdout并从中读取。

编辑:这是我到目前为止的代码,但不起作用。它立即发生了段错误,但我不明白为什么:

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char** argv){
  int ch;
  int fd = stripNewlines();

  while((ch = getc(fd)) != EOF){
    putc(ch, stdout);
  }

  return 0;
}

int stripNewlines(){
  int fd[2], ch;
  pipe(fd);

  if(!fork()){
    close(fd[0]);

    while((ch = getc(stdin)) != EOF){
      if(ch == '\n'){ continue; }
      putc(ch, fd[1]);
    }

    exit(0);
  }else{
    close(fd[1]);

    return fd[0];
  }
}

编辑:原来这是两件事:一个是我的标题没有将stdin和stdout定义为0和1,所以我实际上正在读/写完全随机的管道。另一个原因是由于某种原因,getc和putc不能正常工作,所以我不得不使用read()和write()。如果我这样做,那就完美了:

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char** argv){
  int ch;
  int fd = stripNewlines();

  while(read(fd, &ch, 1) == 1){
    write(1, &ch, 1);
  }

  return 0;
}

int stripNewlines(){
  int fd[2];
  int ch;
  pipe(fd);

  if(!fork()){
    close(fd[0]);

    while(read(0, &ch, 1) == 1){
      if(ch == '\n'){ continue; }
      write(fd[1], &ch, 1);
    }

    exit(0);
  }else{
    close(fd[1]);
    return fd[0];
  }
}

4 个答案:

答案 0 :(得分:1)

stdin读取它会让生活变得更加困难。如果您可以继续阅读其他FILE *,则可以很容易地使用popen()来生成tr,并从它返回的FILE *中读取。

编辑:如果你不能这样做,那么你需要进入一点丑陋。首先使用popen生成tr并重定向其输出。然后使用fileno获取与FILE *stdin相关联的文件编号。最后,使用dup2stdin的文件描述符与来自tr的管道相关联。

答案 1 :(得分:1)

请参阅popen(3)。基本上你需要做的就是

FILE *in = popen("tr <args>", "r");

然后从in读取。

答案 2 :(得分:0)

为什么你不能将tr的输入传递给你的程序?

tr A-Z a-z | myprogram

答案 3 :(得分:0)

#include <stdio.h>
int main()
{
    char x1[100];
    scanf("%[^\n]",x1); // read entire line from tr i.e., from stdin
    printf("\n%s",x1);
}

并使用

  

tr A-Z a-z | myprogram