2010-04-02 9 views
7

Piszę program, który powinien odczytać dane wejściowe przez stdin, więc mam następujący contruct.Jak sprawdzić, czy mój program ma podłączone do niego dane

FILE *fp=stdin; 

Ale to po prostu wisi, jeśli użytkownik nie ma nic rurami do programu, w jaki sposób mogę sprawdzić, czy użytkownik jest rzeczywiście potokiem danych do mojego programu jak

gunzip -c file.gz |./a.out #should work 
./a.out #should exit program with nice msg. 

dzięki

+0

Dla przypomnienia, program nie wisi; to po prostu czekanie na wejście. Jeśli wyślesz EOF (Ctrl-D na większości platform), zostanie to zinterpretowane tak, jakby wejście zakończyło się wcześniej. – greyfade

Odpowiedz

8

Ponieważ używasz odnośniki do plików, trzeba zarówno isatty() i fileno() to zrobić:

#include <unistd.h> 
#include <stdio.h> 

int main(int argc, char* argv[]) 
{ 
    FILE* fp = stdin; 

    if(isatty(fileno(fp))) 
    { 
     fprintf(stderr, "A nice msg.\n"); 
     exit(1); 
    } 

    /* carry on... */ 
    return 0; 
} 

Właściwie, to jest długa droga. Krótko mówiąc, nie należy używać wskaźników plików:

#include <unistd.h> 

int main(int argc, char* argv[]) 
{ 
    if(isatty(STDIN_FILENO)) 
    { 
     fprintf(stderr, "A nice msg.\n"); 
     exit(1); 
    } 

    /* carry on... */ 
    return 0; 
} 

Kilka standardowych programów uniksowych robi to w celu zmodyfikowania ich zachowania. Na przykład, jeśli masz ls skonfigurowany tak, aby dawał ładne kolory, wyłączy kolory, jeśli potwierdzisz jego standardowe wyjście do innego programu.

3

Przekazanie standardowego wejścia do wyboru() lub odpytywania() powinno informować cię, czy wejście oczekuje. W wielu systemach operacyjnych można również stwierdzić, czy stdin to tty czy rura.

EDYCJA: Widzę, że będę musiał podkreślić także część testu tty dla również. Funt nie jest tty, ale może nie być gotowego wejścia przez nieokreślony czas.

+0

Uważam, że PO chciał tylko opisać przypadek "ucieczki z linii poleceń" i "zastanawiam się, dlaczego". Prawdopodobnie próbuje naprawić błąd PEBKAC. Siedzenie w oczekiwaniu na FIFO lub innej fajce byłoby w porządku. –

3

Spróbuj "man isatty", myślę, że ta funkcja powie ci, czy rozmawiasz z użytkownikiem, czy nie.

2

Użyj funkcji isatty, aby wykryć, że standardowe wejście pochodzi z terminala, a nie przekierowanie.

1

Zobacz funkcję "isatty" - jeśli STDIN jest terminalem, możesz pominąć czytanie z niego. Jeśli nie jest to terminal, otrzymujesz dane przesyłane lub przekierowywane i możesz czytać do EOF.

0

Dodatkowa opcja, którą można uzyskać za pomocą opcji select(), ustawia limit czasu odczytu ze stdin (w odniesieniu do pierwszego odczytu ze standardowego wejścia lub kolejnych odczytów ze standardowego wejścia).

Na przykład kodu przy użyciu wybierz na stdin patrz:

How to check if stdin is still opened without blocking?

Powiązane problemy