How to detect Key Presses in C++ (All Platforms)

In this C++ Tutorial, we will discuss how to detect Key Presses. The supposedly simple task of registering a single key press (such as the button “a”) turns out to be a surprisingly hard task.

For starters, there is no “perfect platform-independent” method that will work for all Operating Systems (Either it will not work on some OS’s or it will work on them all, but lack some features). Secondly, there are many different ways of detecting key presses, which causes people to get a little confused.

We will do two things in this tutorial. First we will show you all the different techniques to “detect” key presses, and then we will explore a Platform Independent Solution that will be enough for most situations.


Detecting Key Presses – Techniques

We will first discuss Platform-dependent solutions for detecting key-presses, before discussing a Platform Independent solution. Let’s start with the Windows Operating System.

Here we have a solution which relies on the “windows.h” header file. This import gives us the ability to use the GetKeyState() function. By passing in the correct key code to this function, we can “listen” for that specific key and then execute an action accordingly.

The below code “listens” for the Right Shift key to be pressed, and then terminates the loop and exits the program.

#include <iostream>
#include <conio.h>
#include <windows.h>

int main() {
	char ch;
	int flag = 1;

	while (flag) {
		if(GetKeyState(VK_RSHIFT) & 0x8000) {
			std::cout << "Right Shift key pressed" << std::endl;
			flag = 0;
		}
	}

	return 0;
}

The bit flag 0x8000 determines if the key is currently pressed.

Here is a list of all the possible Key codes, along with their descriptions.

Virtual CodeScan CodeDescription
VK_LBUTTON0x01Left mouse button
VK_RBUTTON0x02Right mouse button
VK_CANCEL0x03Control-break processing
VK_MBUTTON0x04Middle mouse button (three-button mouse)
VK_XBUTTON10x05X1 mouse button
VK_XBUTTON20x06X2 mouse button
VK_BACK0x08BACKSPACE key
VK_TAB0x09TAB key
VK_SHIFT0x10SHIFT key
VK_CONTROL0x11CTRL key
VK_MENU0x12ALT key
VK_PAUSE0x13PAUSE key
VK_CAPITAL0x14CAPS LOCK key
VK_NUMPAD0 to VK_NUMPAD90x60 – 0x69Numpad 0-9 key
VK_F1 to VK_F120x70 – 0x7BFunction key F1 to F12
VK_NUMLOCK0x90NUM LOCK key
VK_SCROLL0x91SCROLL LOCK key
VK_LSHIFT0xA0Left SHIFT key
VK_RSHIFT0xA1Right SHIFT key
VK_LCONTROL0xA2Left CONTROL key
VK_RCONTROL0xA3Right CONTROL key
VK_LMENU0xA4Left MENU key
VK_RMENU0xA5Right MENU key

Detect Key Presses in Windows#2

There is one more technique we can use to detect Key presses in Windows, called _kbhit(). This function is a bit unique in the sense that it only “detects” a keyboard press, it does not “consume” it. This means that if you type “a”, kbhit() will return True, but “a” will still remain. So any subsequent _kbhit() calls will also trigger unless we do something about it.

Let’s take a look at a small piece of code.

#include <conio.h>
#include <stdio.h>

int main( void ) {
   // Display message until key is pressed. 
   while( !_kbhit() )
      _cputs( "Waiting.... " );

   // Use _getch to consume input.
   printf( "\nKey struck was '%c'\n", _getch());
}

As you can see here, “Waiting” will continue to print until we press a key. We then consume the entered key at the end using _getch(), and print it out.

We will talk more about _getch() more at the end of this tutorial.


Detecting Key Presses in Linux

Here is some special code written by someone who wanted to create a “kbhit” for Linux (since it is Windows only). The following code contains a definition for _kbhit(), and then a small piece of code to show it’s working. You can learn more about this code on their website.

#include <stdio.h>
#include <sys/select.h>
#include <termios.h>
#include <stropts.h>
#include <unistd.h>

int _kbhit() {
    static const int STDIN = 0;
    static bool initialized = false;

    if (! initialized) {
        // Use termios to turn off line buffering
        termios term;
        tcgetattr(STDIN, &term);
        term.c_lflag &= ~ICANON;
        tcsetattr(STDIN, TCSANOW, &term);
        setbuf(stdin, NULL);
        initialized = true;
    }

    int bytesWaiting;
    ioctl(STDIN, FIONREAD, &bytesWaiting);
    return bytesWaiting;
}

int main(int argc, char** argv) {
    printf("Press any key");
    while (! _kbhit()) {
        printf(".");
        fflush(stdout);
        usleep(1000);
    }
    return 0;
} 

Platform Independent solution for Key Presses in C++

Let’s discuss a little trick we can use to get a single “character” from our Keyboard. For some situations, this technique will be more than enough. The best part about it is that it is Platform independent!

This technique makes use of the _getch() function which takes a single character as input from the keyboard. It can also capture capital characters.

#include <iostream>
#include <conio.h>

int main() {
	char ch;

	//program pauses here until key is pressed
	ch = _getch();

	if(ch == 'a')
		std::cout << "Key Pressed: a" << std::endl;
	if(ch == 's')
		std::cout << "Key Pressed: s" << std::endl;
    else if(ch == 'A')
		std::cout << "Key Pressed: A" << std::endl;

	return 0;
}

This has a few limitations, such as not being able to detect multiple keys at once, and the fact that it “blocks” the execution of our program until we give some input. You can actually make this work for most situations regardless, especially if you wrap it in a loop (for more than one character).

_getch() uses ASCII codes, so you can use integers instead of characters in your switch-case statements. This is useful for when you are taking input for non-alphabetical characters, like arrow keys.


This marks the end of the How to detect Key Presses in C++ Tutorial. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the tutorial content can be asked in the comments section below.

Subscribe
Notify of
guest
3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments