Как проверить, нажата ли клавиша на 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