如何检测是否有输入在windows上的stdin上等待

How can I detect if there is input waiting on stdin on windows?

本文关键字:windows 上的 stdin 等待 输入 何检测 检测 是否      更新时间:2023-10-16

我想检测Windows中是否有输入在stdin上等待。

我在Linux上使用以下通用结构:

fd_set currentSocketSet;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
int result = 1;
while (result > 0){
    FD_ZERO(&currentSocketSet);
    FD_SET(STDIN, &currentSocketSet);
    result = select(STDIN+1, &currentSocketSet, NULL, NULL, &tv);
    if (result == -1){
        printf("Network Error -- select errored with id=%d.n", errno);
        return;
    } else if (result > 0){
        //...do stuff
    }
}

注意:我不想处理像kbhit这样的键盘和键盘功能。我想要一种方法来完成我的要求。我也不希望第三方库这样做,我希望通过本机Windows库调用来获得答案。

注2:在windows上,上述代码失败,windows错误代码为10038"试图在非套接字上进行操作",这可能意味着windows不支持在STDIN上进行选择。

ReadConsoleInput()文档中所述:

进程可以在其中一个等待函数中指定控制台输入缓冲区句柄,以确定何时存在未读控制台输入。当输入缓冲区不为空时,会用信号通知控制台输入缓冲区句柄的状态。

要确定控制台输入缓冲区中未读输入记录的数量,请使用GetNumberOfConsoleInputEvents函数。要在不影响未读记录数的情况下从控制台输入缓冲区读取输入记录,请使用PeekConsoleInput函数。要丢弃控制台输入缓冲区中的所有未读记录,请使用FlushConsoleInputBuffer函数。

您可以使用GetStdHandle()获取STDIN的句柄,以便在上述函数中使用。

如前所述,在Windows中必须使用GetStdHandle(),并且返回的句柄不能与套接字混合。但幸运的是,返回的句柄可以使用WaitForSingleObject()进行测试,就像Windows中的许多其他句柄一样。因此,你可以这样做:

#include <stdio.h>
#include <windows.h>
BOOL key_was_pressed(void)
{
    return (WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE),0)==WAIT_OBJECT_0);
}
void wait_for_key_press(void)
{
    WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE),INFINITE);
}
int main()
{
    if(key_was_pressed())
        printf("Someone pressed a key beforehandn");
    printf("Wait until a key is pressedn");
    wait_for_key_press();
    if(key_was_pressed())
        printf("Someone pressed a keyn");
    else
        printf("That can't be happening to men");
    return 0;
}

EDIT:忘记说你需要从句柄中读取字符才能键入_was_pressed()返回FALSE。

正如您所知,Linux!=Windows,并且在这两种环境中,"select()"将获得相同的语义。

您也没有指定这是一个Windows GUI程序还是控制台模式程序。这很重要。

然而。。。

您可能想要了解的两个Win32 API:

  • GetAsyncKeyState

  • 对等控制台输入

希望这能帮助

PS:

如果这是一个控制台模式的程序,您将需要一个窗口句柄。调用GetStdHandle(STD_INPUT_HANDLE)获取它。