C++ 如何检测windows上是否有输入等待标准输入?

C++ 如何检测windows上是否有输入等待标准输入?,c++,c,windows,C++,C,Windows,我想检测Windows中是否有输入等待标准输入 我在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 = sel

我想检测Windows中是否有输入等待标准输入

我在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上进行选择。

如中所述:

进程可以在其中一个进程中指定控制台输入缓冲区句柄,以确定何时存在未读的控制台输入。当输入缓冲区不为空时,控制台输入缓冲区句柄的状态将发出信号

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


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

如您所知,Linux!=在这两种环境中,select的语义不会相同

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

。。。然而

您可能希望查看的两个Win32 API:

“希望有帮助

附言:


如果这是一个控制台模式的程序,你需要一个窗口句柄。调用以获取它。

如前所述,在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 beforehand\n");

    printf("Wait until a key is pressed\n");

    wait_for_key_press();

    if(key_was_pressed())
        printf("Someone pressed a key\n");
    else
        printf("That can't be happening to me\n");

    return 0;
}

编辑:忘记说您需要读取句柄中的字符,以便在按下键时返回FALSE

我们假设这是一个控制台应用程序吗?嗯,我不知道Linux,所以我不知道您发布的代码在做什么。但是从我对这个问题的理解来看,ReadConsoleInput函数应该可以工作。你必须手动调用它,它不会给你通知。GetNumberOfConsoleInputEvents和PeekConsoleInput也是选项。在Linux中,select对文件描述符进行操作,其中包括套接字、stdin/out等。在Windows中,select仅对套接字有效,其他任何选项均无效。无法在Windows上将stdin传递给select。请注意,如果已重定向标准输入,则此操作将无法正常工作。如果希望忽略重定向从控制台读取,则应显式打开并读取CONIN$,而不是使用标准输入。如果不想忽略重定向,则需要检查标准输入是否为控制台句柄,并相应地更改行为。我认为最好的方法是在ReadConsoleInput中输入非控制台句柄时检测错误,但也请参见GetFileType。捕获读取错误不是检测输入类型的最佳方法。GetConsoleMode将告诉您输入是否来自真实的控制台。如果需要,GetFileType将告诉您使用的是哪种类型的输入。是的,您是对的:当您要调用ReadConsoleInput时,您可能已经需要知道句柄是否指向控制台。从GetConsoleMode检查错误更有意义。挑剔:套接字是句柄,但并非所有句柄都是套接字。如果标准输入恰好被重定向到套接字句柄,那么select将起作用。在windows中,几乎所有东西都是一个手柄。我应该用恰当的措辞:“套接字不是文件句柄”-