C++ 如何检测windows上是否有输入等待标准输入?
我想检测Windows中是否有输入等待标准输入 我在Linux上使用以下通用结构: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(¤tSocketSet); FD_SET(STDIN, ¤tSocketSet); result = sel
fd_set currentSocketSet;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
int result = 1;
while (result > 0){
FD_ZERO(¤tSocketSet);
FD_SET(STDIN, ¤tSocketSet);
result = select(STDIN+1, ¤tSocketSet, 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中,几乎所有东西都是一个手柄。我应该用恰当的措辞:“套接字不是文件句柄”-