提问人:snivy9014 提问时间:1/12/2017 最后编辑:snivy9014 更新时间:7/19/2021 访问量:197490
如何检查是否在 C++ 上按下了键
How do I check if a Key is pressed on C++
答:
你说的是功能吗?getchar
http://en.cppreference.com/w/c/io/getchar
评论
免责声明:此答案是在编辑问题以将其范围限制为特定操作系统之前提供的
没有便携式功能可以检查是否按下了某个键,如果没有,则继续。这始终取决于系统。
适用于 linux 和其他 posix 兼容系统的解决方案:
在这里,对于 Morgan Mattews 的代码,它以与任何 POSIX 兼容系统兼容的方式提供功能。他使用了在 termios 级别停用缓冲的技巧。kbhit()
Windows解决方案:
对于 Windows,Microsoft 提供 _kbhit()
正如其他人所提到的,没有跨平台的方法可以做到这一点,但在 Windows 上你可以这样做:
下面的代码检查键“A”是否关闭。
if(GetKeyState('A') & 0x8000/*Check if high-order bit is set (1 << 15)*/)
{
// Do stuff
}
如果是班次或类似情况,您将需要通过以下其中一项:https://msdn.microsoft.com/de-de/library/windows/desktop/dd375731(v=vs.85).aspx
if(GetKeyState(VK_SHIFT) & 0x8000)
{
// Shift down
}
低位指示密钥是否切换。
SHORT keyState = GetKeyState(VK_CAPITAL/*(caps lock)*/);
bool isToggled = keyState & 1;
bool isDown = keyState & 0x8000;
哦,也别忘了
#include <Windows.h>
评论
检查是否按下了某个键,如果是,则执行操作
考虑'select()',如果这个(据报道是Posix)函数在你的操作系统上可用。
'select()' 使用 3 组位,您可以使用提供的函数创建这些位(参见 man select、FD_SET 等)。您可能只需要创建输入位(目前)
从手册页:
'select()' “允许程序监视多个文件描述符,等待一个或多个文件描述符”准备好“进行某种类型的 I/O 操作(例如,可能的输入)。如果文件描述符可以执行相应的 I/O 操作(例如,read(2) 而不阻塞...)“,则认为文件描述符已准备就绪。
调用 select 时:
a) 该函数查看集合中标识的每个 FD,如果该 FD 状态表明您可以执行某些操作(也许是读取,也许是写入),则选择将返回并让您执行该操作......“您所要做的就是扫描位,找到设置的位,然后对与该位关联的 FD 执行操作。
第一组(传入 select)包含活动输入 fd(通常是设备)。您可能只需要此集合中的 1 位。只需 1 个 fd(即来自键盘的输入),1 位,这一切都非常简单。通过从 select 返回,您可以“做一些事情”(也许,在您获取字符之后)。
b) 该函数还具有超时功能,您可以使用它来确定等待 FD 状态更改的时间。如果 fd 状态没有改变,超时将导致 'select()' 返回 0。(即无键盘输入)此时,您的代码也可以执行某些操作,例如输出。
仅供参考 - FD 通常为 0,1,2...记住 C 使用 0 作为 STDIN、1 和 STDOUT。
简单的测试设置:我打开一个终端(与我的控制台分开),然后在该终端中键入 tty 命令以查找其 ID。响应通常类似于“/dev/pts/0”,或 3,或 17...
然后我通过使用 open 在“select()”中使用一个 fd:
// flag options are: O_RDONLY, O_WRONLY, or O_RDWR
int inFD = open( "/dev/pts/5", O_RDONLY );
确定此值很有用。
这是一个需要考虑的片段(来自 man select):
fd_set rfds;
struct timeval tv;
int retval;
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(0, &rfds);
/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
/* Don't rely on the value of tv now! */
if (retval == -1)
perror("select()");
else if (retval)
printf("Data is available now.\n"); // i.e. doStuff()
/* FD_ISSET(0, &rfds) will be true. */
else
printf("No data within five seconds.\n"); // i.e. key not pressed
评论
下一个:库和命名空间之间有什么关系?
评论
GetAsyncKeyState()
GetKeyState()