2010-04-21 13 views
6

Mam program C, i chciałbym, aby filtrował wszystkie swoje dane wejściowe za pomocą tr. Tak więc, chciałbym rozpocząć tr jako proces potomny, przekierować stdin do niego, a następnie uchwycić standardowe wyjście i przeczytać z tego.Przekierowanie stdin w programie C do innego procesu

Edytuj: Oto kod, który mam do tej pory, który nie działa. Zwraca błąd natychmiast, ale nie rozumiem dlaczego:

#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: Okazuje się, że był to dwie rzeczy: jedna, że ​​mój nagłówek nie zdefiniował stdin i stdout jak 0 i 1, więc faktycznie czytanie/pisanie do całkowicie przypadkowych rur. Drugim jest to, że z jakiegoś powodu getc i putc nie działają tak, jak się spodziewałem, więc musiałem użyć read() i write(). Jeśli to zrobię, to jest idealne:

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

Odpowiedz

0

Jakiś powód, dla którego po prostu nie możesz odłączyć wejścia od tr do twojego programu?

tr A-Z a-z | myprogram

+0

Tak, ale jest to dość skomplikowane. Chcę sobie z tym poradzić w samym programie. –

1

Czytając ją od stdin czyni życie bardziej trudne. Jeśli możesz żyć z czytaniem z innego FILE *, całkiem łatwo jest użyć popen() do odrodzenia tr i odczytać z FILE *, który powróci.

Edycja: jeśli nie możesz tego zrobić, musisz dostać trochę brzydoty. Zacznij od używania popen do odrodzenia tr z przekierowanym wyjściem. Następnie użyj numeru fileno, aby uzyskać numery plików skojarzone z tym FILE * oraz z stdin. Na koniec użyj dup2, aby skojarzyć deskryptor pliku stdin z potokiem z tr.

+1

Tak, to sprawia, że ​​trudno jest mi zadać pytanie. Gdybym mógł to zrobić, zrobiłbym to. :-) –

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

i używać

tr A-Z a-z | myprogram

1

Zobacz popen(3). Zasadniczo wszystko, co musisz zrobić, to:

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

, a następnie odczytać z in.

Powiązane problemy