2011-06-20 26 views
8

Estoy tratando de usar select() para leer la entrada del teclado y me quedé atrapado en que no sé cómo leer desde el teclado y uso un descriptor de archivo para hacer asi que. Me han dicho que use STDIN y STDIN_FILENO para abordar este problema, pero aún estoy confundido.
¿Cómo puedo hacerlo?Cómo usar select() para leer la entrada desde el teclado en C

+4

Esto es una cosa bastante difícil de hacer si no está familiarizado con la programación POSIX en general. Para empezar, debe configurar los modos de terminal para que el dispositivo no almacene los caracteres recibidos. – antlersoft

+1

No es necesario usar select(), a menos que sea parte de una tarea. Puede simplemente enviar (STDIN ...) o leer (STDIN_FILENO ...). –

+2

Si necesita un control completo de la terminal (pulsación de teclas, etc.), lo más probable es que esté mucho mejor si utiliza una biblioteca de terminales como ** ncurses ** (también hay puertos de Windows). –

Respuesta

5

Su pregunta suena un poco confusa. select() se usa para bloquear hasta que la entrada esté disponible. Pero usted realiza la lectura real con las funciones normales de lectura de archivos (como read, fread, fgetc, etc.).

Aquí hay un ejemplo rápido. Bloquea hasta que stdin tenga al menos un personaje disponible para leer. Pero, por supuesto, a menos que cambie el terminal a un modo sin cocer, bloquea hasta que presione enter, cuando los caracteres ingresados ​​se descarguen en el búfer de archivo (desde un búfer de terminal).

#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

Muchas gracias, esto realmente aclaró mi pregunta. – drum

1

Tal vez, ¿quieres la forma de acceder al teclado en "WINDOWS"? En Windows, no se puede obtener el resultado de select() para STDIN. Deberías usar PeekConsoleInput(). Y utilice la dirección de stdin como siguiendo.

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

stdin puede convertirse en entrada de tubería. si es así, no recibe ninguna entrada de teclado.

P.S. Si no preguntas por Windows, lo siento mucho.

+0

Windows ni siquiera se me ocurrió. Buen ahorro: cubra todos los ángulos. –

4

Como ya se dijo, al usar select puede simplemente controlar, p. stdin para verificar si los datos de entrada ya están disponibles para lectura o no. Si está disponible, puede usar, por ejemplo, fgets para leer de forma segura los datos de entrada en alguna memoria intermedia, como se muestra a continuación:

#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); 
} 
Cuestiones relacionadas