简体   繁体   English

如何检查是否在 C++ 上按下了某个键

[英]How do I check if a Key is pressed on C++

我怎么可能检查是否在 Windows 上按下了某个键?

As mentioned by others there's no cross platform way to do this, but on Windows you can do it like this:正如其他人所提到的,没有跨平台的方法可以做到这一点,但在 Windows 上,您可以这样做:

The Code below checks if the key 'A' is down.下面的代码检查键 'A' 是否按下。

if(GetKeyState('A') & 0x8000/*Check if high-order bit is set (1 << 15)*/)
{
    // Do stuff
}

In case of shift or similar you will need to pass one of these: https://msdn.microsoft.com/de-de/library/windows/desktop/dd375731(v=vs.85).aspx如果发生轮班或类似情况,您将需要通过以下其中一项: https : //msdn.microsoft.com/de-de/library/windows/desktop/dd375731(v=vs.85).aspx

if(GetKeyState(VK_SHIFT) & 0x8000)
{
    // Shift down
}

The low-order bit indicates if key is toggled.低位指示键是否被切换。

SHORT keyState = GetKeyState(VK_CAPITAL/*(caps lock)*/);
bool isToggled = keyState & 1;
bool isDown = keyState & 0x8000;

Oh and also don't forget to哦,也不要忘记

#include <Windows.h>

Disclaimer : This answer was provided before the question was edited to limit its scope to a specific OS免责声明:此答案是在编辑问题以将其范围限制在特定操作系统之前提供的

There is no portable function that allows to check if a key is hit and continue if not.没有便携式功能可以检查键是否被击中,如果没有则继续。 This is always system dependent.这始终取决于系统。

Solution for linux and other posix compliant systems: linux 和其他 posix 兼容系统的解决方案:

Here, for Morgan Mattews's code provide kbhit() functionality in a way compatible with any POSIX compliant system.在这里,对于 Morgan Mattews 的代码,以与任何 POSIX 兼容系统兼容的方式提供kbhit()功能。 He uses the trick of desactivating buffering at termios level.他使用了在 termios 级别停用缓冲的技巧。

Solution for windows:窗户解决方案:

For windows, Microsoft offers _kbhit()对于 Windows,微软提供_kbhit()

check if a key is pressed, if yes, then do stuff检查是否按下了某个键,如果是,则执行操作

Consider 'select()', if this (reportedly Posix) function is available on your os.考虑“select()”,如果这个(据说是 Posix)函数在你的操作系统上可用。

'select()' uses 3 sets of bits, which you create using functions provided (see man select, FD_SET, etc). 'select()' 使用 3 组位,您可以使用提供的函数创建这些位(请参阅 man select、FD_SET 等)。 You probably only need create the input bits (for now)您可能只需要创建输入位(目前)


from man page:从手册页:

'select()' "allow a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" for some class of I/O operation (eg, input possible). A file descriptor is considered ready if it is possible to perform a corresponding I/O operation (eg, read(2) without blocking...)" 'select()'“允许程序监视多个文件描述符,等待一个或多个文件描述符为某类 I/O 操作(例如,可能的输入)“准备好”。如果可以执行相应的 I/O 操作(例如,不阻塞的 read(2) ......)”

When select is invoked:调用 select 时:

a) the function looks at each fd identified in the sets, and if that fd state indicates you can do something (perhaps read, perhaps write), select will return and let you go do that ... 'all you got to do' is scan the bits, find the set bit, and take action on the fd associated with that bit. a) 该函数查看集合中标识的每个 fd,如果该 fd 状态表明您可以执行某些操作(可能是读取,可能是写入),则 select 将返回并让您执行该操作......“所有您必须做的”是扫描位,找到设置位,并对与该位相关联的 fd 采取行动。

The 1st set (passed into select) contains active input fd's (typically devices).第一组(传递到选择)包含活动输入 fd(通常是设备)。 Probably 1 bit in this set is all you will need.可能你只需要这个集合中的 1 位。 And with only 1 fd (ie an input from keyboard), 1 bit, this is all quite simple.并且只有 1 个 fd(即来自键盘的输入)、1 位,这一切都非常简单。 With this return from select, you can 'do-stuff' (perhaps, after you have fetched the char).通过选择返回,您可以“做事”(也许,在您获取字符之后)。

b) the function also has a timeout, with which you identify how much time to await a change of the fd state. b) 该函数还有一个超时时间,您可以用它来确定等待 fd 状态更改的时间。 If the fd state does not change, the timeout will cause 'select()' to return with a 0. (ie no keyboard input) Your code can do something at this time, too, perhaps an output.如果 fd 状态没有改变,超时将导致 'select()' 返回 0。(即没有键盘输入)此时您的代码也可以做一些事情,也许是一个输出。

fyi - fd's are typically 0,1,2... Remembe that C uses 0 as STDIN, 1 and STDOUT. fyi - fd's 通常是 0,1,2... 记住 C 使用 0 作为 STDIN、1 和 STDOUT。


Simple test set up: I open a terminal (separate from my console), and type the tty command in that terminal to find its id.简单的测试设置:我打开一个终端(与我的控制台分开),并在该终端中键入 tty 命令以查找其 ID。 The response is typically something like "/dev/pts/0", or 3, or 17...响应通常类似于“/dev/pts/0”,或 3,或 17 ...

Then I get an fd to use in 'select()' by using open:然后我通过使用 open 得到一个 fd 用于“select()”:

// flag options are: O_RDONLY, O_WRONLY, or O_RDWR
int inFD = open( "/dev/pts/5", O_RDONLY ); 

It is useful to cout this value.计算此值很有用。

Here is a snippet to consider (from man select):这是一个需要考虑的片段(来自 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

Are you talking about getchar function?你说的是getchar函数吗?

http://en.cppreference.com/w/c/io/getchar http://en.cppreference.com/w/c/io/getchar

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM