2013-04-26 28 views
7

Ich suchte, aber keine relevante Antwort auf diese Frage erhalten, ich arbeite an einem Linux-Rechner, ich wollte überprüfen, ob der Standard-Eingangsstrom ein beliebiges Zeichen enthält, ohne die Zeichen aus dem Stream zu entfernen.Überprüfen, ob Stdin leer ist

+1

C++ oder C? Ihre Frage ist mit beiden Tags versehen. –

+3

Ich bin mir nicht sicher, ob deine Frage eine klar definierte Bedeutung hat. Stellen Sie sich vor, dass das * stdin * eine Pipe ist (von einem Befehl, der ewig braucht, um sein erstes Zeichen auf seinem * stdout * auszuspucken). Sie könnten [poll (2)] (http://man7.org/linux/man-pages/man2/poll.2.html) aufrufen, indem Sie 'STDIN_FILENO' (d. H. 0) als Dateideskriptor verwenden. Sie überprüfen dann, ob * stdin * lesbar ist ... (d. H., Dass [read (2)] (http://man7.org/linux/man-pages/man2/read.2.html) nicht blockiert). –

Antwort

6

Sie können versuchen, select() Funktion, und warten auf Daten in den Eingabedatenstrom.

Beschreibung:

select() und pselect() erlauben ein Programm mehrere Datei Deskriptoren zu überwachen, bis eine oder mehrere der Filedeskriptoren warten werden „bereit“ für einige Klasse der E/A-Operation (z. B. Eingabe möglich). Eine Datei Deskriptor wird als bereit betrachtet, wenn es möglich ist, die entsprechende E/A-Operation (z. B. Lesen (2)) ohne Blockierung durchzuführen.

In Ihrem Fall wird die Dateideskriptor stdin sein

void yourFunction(){ 
    fd_set fds; 
    struct timeval timeout; 
    int selectRetVal; 

    /* Set time limit you want to WAIT for the fdescriptor to have data, 
     or not(you can set it to ZERO if you want) */ 
    timeout.tv_sec = 0; 
    timeout.tv_usec = 1; 

    /* Create a descriptor set containing our remote socket 
     (the one that connects with the remote troll at the client side). */ 
    FD_ZERO(&fds); 
    FD_SET(stdin, &fds); 

    selectRetVal = select(sizeof(fds)*8, &fds, NULL, NULL, &timeout); 

    if (selectRetVal == -1) { 
     /* error occurred in select(), */ 
     printf("select failed()\n"); 
    } else if (selectRetVal == 0) { 
     printf("Timeout occurred!!! No data to fetch().\n"); 
     //do some other stuff 
    } else { 
     /* The descriptor has data, fetch it. */ 
     if (FD_ISSET(stdin, &fds)) { 
      //do whatever you want with the data 
     } 
    } 
} 

Hoffe, es hilft.

+3

Danke für eine Instant-Rply, aber ich möchte nicht auf den Datenstrom warten, um die Daten zu haben, Es ist nur das, wenn der Stream Daten hat, muss ich einige Verarbeitung tun, wenn es keine Daten hat, tun einige andere Verarbeitung. Der Code sollte nicht auf die Eingabe warten, – 51k

+0

Ich denke immer noch, dass das @ 51k helfen könnte, lassen Sie mich ein Beispiel geben. –

4

cacho war auf dem richtigen Weg, aber select ist nur erforderlich, wenn Sie mit mehr als einem Dateideskriptor zu tun hat, und stdin ist keine POSIX-Dateibeschreibung (int); Es ist ein FILE *. Sie möchten STDIN_FILENO verwenden, wenn Sie diese Route gehen.

Es ist auch keine sehr saubere Route zu nehmen. Ich würde lieber poll verwenden. Wenn Sie 0 als timeout angeben, wird die Abfrage sofort zurückgegeben.

Falls keine der definierten Ereignissen auf jedem ausgewählten Datei Deskriptor aufgetreten sind, poll() soll mindestens Timeout Millisekunden warten ein Ereignis auf eine der ausgewählten Datei-Deskriptoren auftreten. Wenn der Wert des Timeouts 0 ist, soll poll() sofort zurückkehren. Wenn der Wert Timeout -1 ist, wird poll() blockiert, bis ein angefordertes Ereignis auftritt, oder , bis der Anruf unterbrochen wird.

struct pollfd stdin_poll = { .fd = STDIN_FILENO 
          , .events = POLLIN | POLLRDBAND | POLLRDNORM | POLLPRI }; 
if (poll(&stdin_poll, 1, 0) == 1) { 
    /* Data waiting on stdin. Process it. */ 
} 
/* Do other processing. */