Как проверить, нажата ли клавиша на C++ [закрыто]

Как я могу проверить, нажата ли клавиша на Windows?

4 ответов


как упоминалось другими, для этого нет кросс-платформенного способа, но в 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>

апоплогии, если это выглядит немного сжато-еще не понял, как сделать пустые строки


нет портативной функции, которая позволяет проверить, нажата ли клавиша, и продолжить, если нет. Это всегда зависит от системы.

решение для linux и других систем, совместимых с posix:

вот, для кода Моргана Мэттьюса обеспечить kbhit() функциональность в пути совместимом с любой системой POSIX уступчивой. Он использует трюк деактивации буферизации на уровне termios.

раствор для windows:

для windows, Microsoft предлагает _kbhit()


проверьте, нажата ли клавиша, если да, то сделайте вещи

рассмотрим " select ()", если эта (как сообщается, Posix) функция доступна на вашей ОС.

'select ()' использует 3 набора битов, которые вы создаете, используя предоставленные функции (см. man select, FD_SET и т. д.). Вам, вероятно, нужно только создать входные биты (на данный момент)


из man page:

' select ()' " разрешить программе отслеживать несколько файловых дескрипторов, дожидаясь одного или несколько файловых дескрипторов становятся "готовыми" для некоторого класса операций ввода-вывода (например, возможен ввод). Файловый дескриптор считается готовым, если есть возможность выполнить соответствующую операцию ввода-вывода(например, чтение (2) Без блокировки...)"

при вызове select:

a) функция смотрит на каждый FD, идентифицированный в наборах, и если это состояние FD указывает, что вы можете что-то сделать (возможно, прочитать, возможно, написать), select вернет и позволит вам сделать это ... - все, что у тебя есть . для этого нужно сканировать биты, найти бит набора и принять меры по FD, связанному с этим битом.

1-й набор (переданный в select) содержит активные входные fd (обычно устройства). Наверное, 1 бит в этом наборе есть все, что вам нужно. И только с 1 fd (т. е. вход с клавиатуры), 1 бит, все это довольно просто. С этим возвращением из select вы можете "делать вещи" (возможно, после того, как вы принесли char).

b) функция также имеет тайм-аут, с которым вы идентифицируете сколько времени ждать изменения состояния fd. Если состояние fd не изменится, тайм-аут заставит 'select ()' вернуться с 0. (т. е. нет ввода с клавиатуры) ваш код может что-то сделать в это время, возможно, выход.

fyi-fd, как правило, 0,1,2... Помните, что C использует 0 как STDIN, 1 и STDOUT.


Простая настройка теста: я открываю терминал (отдельно от моей консоли) и набираю команду tty в этом терминале, чтобы найти его идентификатор. Ответ обычно что-то вроде "/dev/pts/0", или 3, или 17...

затем я получаю fd для использования в " select ()", используя open:

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

полезно cout это значение.

вот фрагмент для рассмотрения (от 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