Перенаправить стандартный ввод в программе на C в другой процесс - PullRequest
6 голосов
/ 21 апреля 2010

У меня есть программа на C, и я бы хотел, чтобы она фильтровала все свои входные данные с помощью tr. Итак, я бы хотел запустить tr как дочерний процесс, перенаправить мой stdin на него, затем перехватить stdout tr и прочитать его.

Редактировать: вот код, который у меня есть, который не работает. Это происходит мгновенно, но я не понимаю, почему:

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

1 голос
/ 21 апреля 2010

См. popen(3). В общем, все, что вам нужно сделать, это

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

, а затем читать из in.

1 голос
/ 21 апреля 2010

Чтение из stdin усложняет жизнь. Если вы можете жить с чтением из другого FILE *, довольно просто использовать popen() для вызова tr, и читать из FILE *, которое он возвращает.

Редактировать: если вы не можете этого сделать, то вам нужно немного впасть в уродство. Начните с использования popen для появления tr с перенаправленным выводом. Затем используйте fileno, чтобы получить номера файлов, связанных с этим FILE * и с stdin. Наконец, используйте dup2, чтобы связать дескриптор файла stdin с каналом из tr.

0 голосов
/ 21 апреля 2010
#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

0 голосов
/ 21 апреля 2010

Любая причина, почему вы просто не можете передать ввод от tr в вашу программу?

tr A-Z a-z | myprogram

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...