10 Stimmen

Wie man select() verwendet, um Eingaben von der Tastatur in C zu lesen

Ich versuche, select() zu verwenden, um Tastatureingaben zu lesen, und ich stecke fest, weil ich nicht weiß, wie man von der Tastatur liest und einen Dateideskriptor dafür verwendet. Man hat mir gesagt, ich solle STDIN und STDIN_FILENO verwenden, um dieses Problem anzugehen, aber ich bin immer noch verwirrt.
Wie kann ich das tun?

4 Stimmen

Dies ist eine ziemlich schwierige Aufgabe, wenn Sie mit der POSIX-Programmierung im Allgemeinen nicht vertraut sind. Zum einen müssen Sie die Terminalmodi so einstellen, dass das Gerät empfangene Zeichen nicht puffert.

1 Stimmen

Sie brauchen select( ) nicht zu verwenden, es sei denn, es ist Teil einer Hausaufgabe. Sie können einfach fread( STDIN ... ) oder read( STDIN_FILENO ... ) verwenden.

2 Stimmen

Wenn Sie die volle Kontrolle über das Terminal benötigen (Tastendruck usw.), werden Sie höchstwahrscheinlich viel Besser ist es, eine Terminalbibliothek zu verwenden wie ncurses (es gibt auch Windows-Ports).

6voto

luser droog Punkte 18279

Ihre Frage klingt ein wenig verworren. select() wird verwendet, um die Eingabe zu blockieren, bis sie verfügbar ist. Das eigentliche Lesen erfolgt jedoch mit normalen Dateilesefunktionen (wie read , fread , fgetc , usw.).

Hier ist ein kurzes Beispiel. Es blockiert, bis stdin mindestens ein Zeichen zum Lesen zur Verfügung hat. Solange Sie das Terminal nicht in einen ungekochten Modus schalten, blockiert es natürlich, bis Sie die Eingabetaste drücken, woraufhin alle eingegebenen Zeichen in den Dateipuffer (von einem Terminalpuffer) gespült werden.

#include <stdio.h>
#include <sys/select.h>

int main(void) {
    fd_set s_rd, s_wr, s_ex;
    FD_ZERO(&s_rd);
    FD_ZERO(&s_wr);
    FD_ZERO(&s_ex);
    FD_SET(fileno(stdin), &s_rd);
    select(fileno(stdin)+1, &s_rd, &s_wr, &s_ex, NULL);
    return 0;
}

0 Stimmen

Vielen Dank, das hat meine Frage wirklich geklärt.

6voto

jwaliszko Punkte 16494

Wie bereits erwähnt, wird durch die Verwendung von Wählen Sie können Sie einfach z.B. stdin überwachen, um zu prüfen, ob die Eingabedaten bereits zum Lesen verfügbar sind oder nicht. Wenn sie verfügbar sind, können Sie z. B. fgets um Eingabedaten sicher in einen Puffer zu lesen, wie unten gezeigt:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    fd_set rfds;
    struct timeval tv;
    int retval, len;
    char buff[255] = {0};

    /* Watch stdin (fd 0) to see when it has input. */
    FD_ZERO(&rfds);
    FD_SET(0, &rfds);

    /* Wait up to five seconds. */
    tv.tv_sec = 5;
    tv.tv_usec = 0;

    retval = select(1, &rfds, NULL, NULL, &tv);

    if (retval == -1){
        perror("select()");
        exit(EXIT_FAILURE);
    }
    else if (retval){
        /* FD_ISSET(0, &rfds) is true so input is available now. */

        /* Read data from stdin using fgets. */
        fgets(buff, sizeof(buff), stdin);

        /* Remove trailing newline character from the input buffer if needed. */
        len = strlen(buff) - 1;
        if (buff[len] == '\n')
            buff[len] = '\0';

        printf("'%s' was read from stdin.\n", buff);
    }
    else
        printf("No data within five seconds.\n");            

    exit(EXIT_SUCCESS);
}

1voto

mattn Punkte 7243

Vielleicht möchten Sie die Tastatureingabe unter "Windows" abfragen? Unter Windows kann das Ergebnis von select() für STDIN nicht abgerufen werden. Sie sollten PeekConsoleInput() verwenden. Und verwenden Sie das Handle von stdin wie folgt.

hStdin = CreateFile("CONIN$", GENERIC_READ|GENERIC_WRITE, ...

stdin kann zur Pipe-Eingabe werden. Wenn dies der Fall ist, erhalten Sie keine Tastatureingabe.

P.S. Wenn Sie nicht nach Windows fragen, tut mir das sehr leid.

0 Stimmen

An Windows habe ich gar nicht gedacht. Nette Rettung: alle Blickwinkel abdecken.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X