C++ Detect when user presses arrow key
// Example for inputting a single keystroke in C++ on Linux
// by Adam Pierce <[email protected]> on http://www.doctort.org/adam/nerd-notes/reading-single-keystroke-on-linux.html
// This code is freeware. You are free to copy and modify it any way you like.
// Modify by me Putra Kusaeri
#include <iostream>
#include <termios.h>
#define STDIN_FILENO 0
using namespace std;
int main()
{
// Black magic to prevent Linux from buffering keystrokes.
struct termios t;
tcgetattr(STDIN_FILENO, &t);
t.c_lflag &= ~ICANON;
tcsetattr(STDIN_FILENO, TCSANOW, &t);
// Once the buffering is turned off, the rest is simple.
cout << "Enter a character: ";
char c,d,e;
cin >> c;
cin >> d;
cin >> e;
cout << "\nYour character was ";
// Using 3 char type, Cause up down right left consist with 3 character
if ((c==27)&&(d=91)) {
if (e==65) { cout << "UP";}
if (e==66) { cout << "DOWN";}
if (e==67) { cout << "RIGHT";}
if (e==68) { cout << "LEFT";}
}
return 0;
}
reference
#include <conio.h>
#include <iostream>
using namespace std;
#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_LEFT 75
#define KEY_RIGHT 77
int main()
{
int c = 0;
while(1)
{
c = 0;
switch((c=getch())) {
case KEY_UP:
cout << endl << "Up" << endl;//key up
break;
case KEY_DOWN:
cout << endl << "Down" << endl; // key down
break;
case KEY_LEFT:
cout << endl << "Left" << endl; // key left
break;
case KEY_RIGHT:
cout << endl << "Right" << endl; // key right
break;
default:
cout << endl << "null" << endl; // not arrow
break;
}
}
return 0;
}
output like this:
Up
Down
Right
Left
Up
Left
Right
Right
Up
detected arrow key press!
The previous answer by arbboter is close but neglects the fact the arrow keys (and other special keys) return a scan code of two characters. The first is either (0) or (224) indicating the key is an extended one; the second contains the scan code value.
Without accounting for this, the ASCII values for "H", "K", "M", and "P" are misinterpreted as "Up", "Down", "Left", and "Right".
Here's a modified version of arbboter's code to demonstrate reading the extended value when one of the arrow keys is pressed:
#include <conio.h>
#include <iostream>
using namespace std;
#define KEY_UP 72
#define KEY_LEFT 75
#define KEY_RIGHT 77
#define KEY_DOWN 80
int main()
{
int c, ex;
while(1)
{
c = getch();
if (c && c != 224)
{
cout << endl << "Not arrow: " << (char) c << endl;
}
else
{
switch(ex = getch())
{
case KEY_UP /* H */:
cout << endl << "Up" << endl;//key up
break;
case KEY_DOWN /* K */:
cout << endl << "Down" << endl; // key down
break;
case KEY_LEFT /* M */:
cout << endl << "Left" << endl; // key left
break;
case KEY_RIGHT: /* P */
cout << endl << "Right" << endl; // key right
break;
default:
cout << endl << (char) ex << endl; // not arrow
break;
}
}
}
return 0;
}
Here is an alternate way to do it without getch() using events (well commented and i tried to make it as simple as i could)
#include <iostream>
#include <Windows.h>
int main(int argc, char *argv[]){
HANDLE rhnd = GetStdHandle(STD_INPUT_HANDLE); // handle to read console
DWORD Events = 0; // Event count
DWORD EventsRead = 0; // Events read from console
bool Running = true;
//programs main loop
while(Running) {
// gets the systems current "event" count
GetNumberOfConsoleInputEvents(rhnd, &Events);
if(Events != 0){ // if something happened we will handle the events we want
// create event buffer the size of how many Events
INPUT_RECORD eventBuffer[Events];
// fills the event buffer with the events and saves count in EventsRead
ReadConsoleInput(rhnd, eventBuffer, Events, &EventsRead);
// loop through the event buffer using the saved count
for(DWORD i = 0; i < EventsRead; ++i){
// check if event[i] is a key event && if so is a press not a release
if(eventBuffer[i].EventType == KEY_EVENT && eventBuffer[i].Event.KeyEvent.bKeyDown){
// check if the key press was an arrow key
switch(eventBuffer[i].Event.KeyEvent.wVirtualKeyCode){
case VK_LEFT:
case VK_RIGHT:
case VK_UP:
case VK_DOWN: // if any arrow key was pressed break here
std::cout<< "arrow key pressed.\n";
break;
case VK_ESCAPE: // if escape key was pressed end program loop
std::cout<< "escape key pressed.\n";
Running = false;
break;
default: // no handled cases where pressed
std::cout<< "key not handled pressed.\n";
break;
}
}
} // end EventsRead loop
}
} // end program loop
return 0;
}
(Thanks to a commenter I now know this code is not standard, though it will work if you compile with g++
, more info in the comments)