如何检测窗口上的stdin是否有输入?

时间:2014-04-19 00:48:06

标签: c++ c windows

我想检测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上,上面的代码失败,窗口错误代码为10038"尝试对不是套接字的操作进行操作"这可能意味着Windows不支持在STDIN上选择。

3 个答案:

答案 0 :(得分:5)

ReadConsoleInput() documentation中所述:

  

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

     

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

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

答案 1 :(得分:1)

如你所知,Linux!= Windows,并且 " select()"在这两种环境中。

您也没有指定这是Windows GUI还是控制台模式程序。它有所作为。

......但是......

您可能需要查看两个Win32 API:

'希望有所帮助

PS:

如果这是一个控制台模式程序,您将需要一个窗口句柄。致电GetStdHandle(STD_INPUT_HANDLE)即可获得。

答案 2 :(得分:1)

正如已经指出的那样,在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;
}

编辑:忘了说你需要从句柄中读取字符才能使key_was_pressed()返回FALSE。