开发者

Redirect stdin in C program to another process

开发者 https://www.devze.com 2022-12-28 02:52 出处:网络
I have a C program, and I\'d like to have it filter all its input with tr. So, I\'d like to start up tr as a child process, redirect my stdin to it, then capture tr\'s stdout and read from that.

I have a C program, and I'd like to have it filter all its input with tr. So, I'd like to start up tr as a child process, redirect my stdin to it, then capture tr's stdout and read from that.

Edit: here's the code I have so far, which doesn't work. It segfaults instantly, but I don't understand why:

#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];
  }
}

Edit: Turns out this was two things: one was that my header didn't define stdin and stdout as 0 and 1, so I was actually reading/writing to totally random pipes. The other is that for some reason getc and putc don't work how I'd expect, so I had to use read() and write() instead. If I do that, it's perfect:

#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];
  }
}


Reading it from stdin makes life more difficult. If you can live with reading from another FILE *, it's pretty easy to use popen() to spawn tr, and read from the FILE * it returns.

Edit: if you can't do that, then you need to get into a bit of ugliness. Start with using popen to spawn tr with its output redirected. Then use fileno to get the file numbers associated with that FILE * and with stdin. Finally, use dup2 to associate stdin's file descriptor with the pipe from tr.


See popen(3). Basically all you need to do is

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

and then read from in.


Any reason why you just can't pipe the input from tr to your program?

tr A-Z a-z | myprogram


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

and use

tr A-Z a-z | myprogram

0

精彩评论

暂无评论...
验证码 换一张
取 消