如何在C中使用select()从键盘读取输入

如何在C中使用select()从键盘读取输入,c,keyboard,stdin,textinput,select-function,C,Keyboard,Stdin,Textinput,Select Function,我试图使用select来读取键盘输入,但我陷入了这样的困境:我不知道如何从键盘读取,如何使用文件描述符来读取。我被告知使用STDIN和STDIN_FILENO来解决这个问题,但我仍然感到困惑。 我怎么做?你的问题听起来有点困惑。选择用于阻止,直到输入可用。但是,您可以使用诸如read、fread、fg等常规文件读取功能进行实际读取 这里有一个简单的例子。它会一直阻塞,直到标准输入至少有一个字符可供读取。但当然,除非您将终端更改为未煮熟的模式,否则它会一直阻塞,直到您按enter键时,键入的任何字

我试图使用select来读取键盘输入,但我陷入了这样的困境:我不知道如何从键盘读取,如何使用文件描述符来读取。我被告知使用STDIN和STDIN_FILENO来解决这个问题,但我仍然感到困惑。
我怎么做?

你的问题听起来有点困惑。选择用于阻止,直到输入可用。但是,您可以使用诸如read、fread、fg等常规文件读取功能进行实际读取

这里有一个简单的例子。它会一直阻塞,直到标准输入至少有一个字符可供读取。但当然,除非您将终端更改为未煮熟的模式,否则它会一直阻塞,直到您按enter键时,键入的任何字符都会从某个终端缓冲区刷新到文件缓冲区

#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;
}

也许,你想要在WINDOWS上查看键盘输入的方法? 在windows上,它无法从标准输入的选择中获取结果。您应该使用Peek控制台输入。 并使用标准DIN的手柄,如下所示

hStdin = CreateFile("CONIN$", GENERIC_READ|GENERIC_WRITE, ...
标准输入可能成为管道输入。如果是这样,你就不会得到任何键盘输入


另外,如果您没有询问Windows,非常抱歉。

如前所述,通过使用stdin等,您只需监控输入数据是否已可供读取。如果可用,您可以使用(例如)将输入数据安全地读取到某个缓冲区,如下所示:

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

如果您通常不熟悉POSIX编程,那么这是一件相当棘手的事情。首先,你必须设置终端模式,这样设备就不会缓冲接收到的字符。不需要使用select,当然,除非它是家庭作业的一部分。你可以让弗雷德·斯丁。。。或读取标准文件号。如果您需要完全按终端控制键等,您很可能会更好地使用像ncurses这样的终端库,也有Windows端口。。。如果消息在用户按键之前到达套接字,则不会像select那样快速返回。在Linux中,我使用select。在Windows中更难。你能澄清一下为什么需要选择来读取键盘输入吗?通常,当您需要读取一系列描述符或输入时,应使用select调用,因为它允许程序监视多个文件描述符,等待一个或多个文件描述符准备好进行某种类型的I/O操作,例如,可能的输入。我甚至没有想到Windows。漂亮的扑救:覆盖所有角度。非常感谢,这确实澄清了我的问题。