2010-04-21 3 views
6

Ho un programma in C, e mi piacerebbe farlo filtrare tutto il suo input con tr. Quindi, mi piacerebbe avviare tr come processo figlio, reindirizzare il mio stdin ad esso, quindi catturare lo stdout di tr e leggerlo da quello.Reindirizzare lo stdin nel programma C in un altro processo

Modifica: ecco il codice che ho finora, che non funziona. Si segfaults istantaneamente, ma io non capisco perché:

#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: Si scopre che questo è stato due cose: uno era che il mio colpo di testa non ha definito stdin e stdout come 0 e 1, così mi è stato effettivamente leggendo/scrivere su pipe totalmente casuali. L'altro è che per qualche ragione getc e putc non funzionano come mi aspetterei, quindi ho dovuto usare invece read() e write(). Se lo faccio, è perfetto:

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

risposta

0

Qual è il motivo per cui proprio non possibile reindirizzare l'input da TR al vostro programma?

tr A-Z a-z | myprogram

+0

Sì, ma è un po 'complicato entrare. Voglio gestire tutto questo all'interno del programma stesso. –

1

lettura da stdin rende la vita più difficile. Se riesci a vivere leggendo da un altro FILE *, è abbastanza facile usare popen() per generare spa tr e leggere dallo FILE * restituito.

Modifica: se non puoi farlo, allora devi entrare in un po 'di bruttezza. Inizia con l'utilizzo di popen per generare spa tr con l'output reindirizzato. Quindi utilizzare fileno per ottenere i numeri di file associati a quello FILE * e con stdin. Infine, utilizzare dup2 per associare il descrittore di file stdin alla pipe da tr.

+1

Sì, rende abbastanza difficile che ho dovuto fare la domanda. Se potessi farlo, lo farei. :-) –

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

e utilizzare

tr A-Z a-z | mioprogramma

1

Vedere popen(3). In pratica tutto quello che dovete fare è

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

e poi leggere da in.