如何检测 Windows 上的 stdin 是否有输入等待?

问题描述 投票:0回答:3

我想检测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 上进行选择。

c++ c windows stdin
3个回答
7
投票

ReadConsoleInput()
文档中所述

进程可以在“等待函数”之一中指定控制台输入缓冲区句柄,以确定何时有未读的控制台输入。当输入缓冲区不为空时,将发出控制台输入缓冲区句柄的状态信号。 要确定控制台输入缓冲区中未读输入记录的数量,请使用

GetNumberOfConsoleInputEvents

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

您可以使用

GetStdHandle()

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


4
投票
GetStdHandle()

并且返回的句柄不能与套接字混合。但幸运的是,返回的句柄可以用

WaitForSingleObject()
进行测试,就像 Windows 中的许多其他句柄一样。 Therefere,你可以这样做:

#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。 


1
投票
不会

在两种环境中获得相同的“select()”语义。 您也没有指定这是 Windows GUI 还是控制台模式程序。这会有所不同。

...但是...

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

  • 获取AsyncKeyState

  • PeekConsole输入

  • '希望有帮助

PS:

如果这是一个控制台模式程序,您将需要一个窗口句柄。调用

GetStdHandle(STD_INPUT_HANDLE)

获取它。

© www.soinside.com 2019 - 2024. All rights reserved.