Search code examples
c++switch-statementgetch

C++ — Arrow key press detection with getch() prints some words inexplicably


I have a simple program that can detect arrow key presses from the user, though I have two questions. But First, here's the code:

#include <iostream>
#include <conio.h>
#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_LEFT 77
#define KEY_RIGHT 75

using namespace std;

int main()
{
    while(1)
    {
        char c = getch();
        cout << "Hello";
        switch(c) {
        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 << "Right" << endl;  // key right
            break;
        case KEY_RIGHT:
            cout << endl << "Left" << endl;  // key left
            break;
        default:
            cout << endl << "NULL" << endl;  // any other key
            break;
        }
    }
    return 0;
}

Question 1: Whenever I press any arrow key, why does it print "Hello" TWICE?

Question 2: Whenever I press any arrow or non-arrow key, it prints the default switch case, "NULL", which is supposed to be only for non-arrow keys. Why is this?

Thanks


Solution

  • When reading keys with conio and getch, in order to be able to handle special keys (arrow keys, function keys) while still fitting its return value in a char, getch returns special keys as two-char sequences. The first call returns 0 (or 0xe0, depending on the C++ implementation you're using), while the second call returns the code of the special key. (Otherwise, your KEY_DOWN - ASCII 80 - by itself would be 'P'.)

    MSDN has more info.

    One approach to putting all of this together would be something like the following:

    char c = getch();
    if (c == 0) {
        switch(getch()) {
            // special KEY_ handling here
            case KEY_UP:
                break;
        }
    } else {
        switch(c) {
            // normal character handling
            case 'a':
                break;
        }
     }