2010-04-21 7 views
6

J'ai un programme C, et j'aimerais qu'il filtre toutes ses entrées avec tr. Donc, j'aimerais commencer tr comme un processus enfant, rediriger mon stdin, puis capturer tr stdout et lire à partir de cela. Edit: voici le code que j'ai jusqu'à présent, qui ne fonctionne pas. Il segfaults instantanément, mais je ne comprends pas pourquoi:Rediriger stdin dans le programme C vers un autre processus

#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: Active c'était deux choses: l'une est que ma tête n'a pas défini stdin et stdout comme 0 et 1, alors que je fait la lecture/écrire à des tuyaux totalement aléatoires. L'autre est que pour une raison quelconque, getc et putc ne fonctionnent pas comme je l'attendais, donc j'ai dû utiliser read() et write() à la place. Si je fais cela, c'est parfait:

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

Répondre

0

Une raison pour laquelle vous ne pouvez simplement pas diriger l'entrée de tr vers votre programme?

tr A-Z a-z | myprogram

+0

Oui, mais c'est un peu compliqué. Je veux gérer tout cela dans le programme lui-même. –

1

lecture à partir stdin rend la vie plus difficile. Si vous pouvez vivre avec la lecture d'un autre FILE *, il est assez facile d'utiliser popen() pour engendrer tr, et lire à partir du FILE * il revient. Edit: si vous ne pouvez pas faire cela, alors vous devez entrer dans un peu de laideur. Commencez par utiliser popen pour générer tr avec sa sortie redirigée. Ensuite, utilisez fileno pour obtenir les numéros de fichiers associés à cette FILE * et stdin. Enfin, utilisez dup2 pour associer le descripteur de fichier stdin au canal tr.

+1

Oui, ça rend assez difficile que je devais poser la question. Si je pouvais le faire, je le ferais. :-) –

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); 
} 

et en utilisant

tr A-Z a-z | myprogram

1

Voir popen(3). Fondamentalement, tout ce que vous devez faire est

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

puis de in.