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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6418232/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 08:59:01  来源:igfitidea点击:

How to use select() to read input from keyboard in C

ckeyboardstdintextinputselect-function

提问by drum

I am trying to use select() to read keyboard input and I got stuck in that I do not know how to read from keyboard and use a file descriptor to do so. I've been told to use STDIN and STDIN_FILENO to approach this problem but I am still confused.
How can I do it?

我正在尝试使用 select() 来读取键盘输入,但我陷入了困境,因为我不知道如何从键盘读取并使用文件描述符来执行此操作。有人告诉我使用 STDIN 和 STDIN_FILENO 来解决这个问题,但我仍然很困惑。
我该怎么做?

采纳答案by luser droog

Youre question sounds a little confused. select()is used to block until input is available. But you do the actual reading with normal file-reading functions (like read,fread,fgetc, etc.).

你的问题听起来有点困惑。select()用于阻塞直到输入可用。但是,你有正常的文件读取功能(如实际读数readfreadfgetc,等)。

Here's a quick example. It blocks until stdin has at least one character available for reading. But of course unless you change the terminal to some uncooked mode, it blocks until you press enter, when any characters typed are flushed into the file buffer (from some terminal buffer).

这是一个快速示例。它阻塞直到 stdin 至少有一个字符可供读取。但是当然,除非您将终端更改为某种未煮过的模式,否则它会阻塞,直到您按 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;
}

回答by jwaliszko

As it was already said, by using selectyou can just monitor e.g. stdin to check if the input data is already available for reading or not. If it is available, you can then use e.g. fgetsto safely read input data to some buffer, like shown below:

正如已经说过的,通过使用select您可以只监视例如 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] = '
hStdin = CreateFile("CONIN$", GENERIC_READ|GENERIC_WRITE, ...
'; printf("'%s' was read from stdin.\n", buff); } else printf("No data within five seconds.\n"); exit(EXIT_SUCCESS); }

回答by mattn

Perhaps, you want the way to peek keyboard input on "WINDOWS"? On windows, it can't get result from select() for STDIN. You should use PeekConsoleInput(). And use handle of stdin like following.

也许,您想要在“WINDOWS”上查看键盘输入的方式?在 Windows 上,它无法从 STDIN 的 select() 获得结果。您应该使用 PeekConsoleInput()。并使用标准输入的句柄,如下所示。

##代码##

stdin may become pipe input. if so, you don't get any keyboard input.

stdin 可能成为管道输入。如果是这样,您将无法获得任何键盘输入。

P.S. If you don't ask about Windows, Sorry much.

PS如果你不问Windows,非常抱歉。