Как использовать select () для чтения ввода с клавиатуры в C - PullRequest
9 голосов
/ 21 июня 2011

Я пытаюсь использовать select () для чтения ввода с клавиатуры, и я застрял в том, что я не знаю, как читать с клавиатуры, и для этого использую файловый дескриптор. Мне сказали использовать STDIN и STDIN_FILENO для решения этой проблемы, но я все еще в замешательстве.
Как я могу это сделать?

Ответы [ 3 ]

5 голосов
/ 02 сентября 2013

Как уже было сказано, с помощью выберите вы можете просто контролировать, например, stdin, чтобы проверить, доступны ли входные данные для чтения или нет. Если он доступен, вы можете использовать, например, fgets для безопасного считывания входных данных в некоторый буфер, как показано ниже:

#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);
}
5 голосов
/ 21 июня 2011

Ваш вопрос звучит немного запутанным.select() используется для блокировки до тех пор, пока не будет доступен ввод.Но вы выполняете фактическое чтение с помощью обычных функций чтения файлов (например, read, fread, fgetc и т. Д.).

Вот краткий пример.Он блокируется, пока в stdin не появится хотя бы один символ, доступный для чтения.Но, конечно, если вы не переключите терминал в какой-нибудь сырой режим, он будет блокироваться до тех пор, пока вы не нажмете клавишу ввода, когда любые введенные символы будут сброшены в буфер файлов (из некоторого буфера терминала).

#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;
}
1 голос
/ 21 июня 2011

Может быть, вы хотите посмотреть способ ввода с клавиатуры на «WINDOWS»?В Windows он не может получить результат от select () для STDIN.Вы должны использовать PeekConsoleInput ().И используйте дескриптор stdin, как показано ниже.

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

stdin может стать вводом канала.если это так, вы не получаете никакого ввода с клавиатуры.

PS Если вы не спрашиваете о Windows, извините очень.

...