getch and arrow codes

2019-01-05 02:03发布

I'm writing a programm that's using getch() to scan for arrow keys. My code so far is:

switch(getch()) {
    case 65:    // key up
        break;
    case 66:    // key down
        break;
    case 67:    // key right
        break;
    case 68:    // key left
        break;
}

Problem is that when I press 'A', 'B', 'C' or 'D' the code will also executed, because 65 is the decimal code for 'A', etc...

Is there a way to check for an arrow key without call others?

Thanks!

10条回答
We Are One
2楼-- · 2019-01-05 02:10

By pressing one arrow key getch will push three values into the buffer:

  • '\033'
  • '['
  • 'A', 'B', 'C' or 'D'

So the code will be something like this:

if (getch() == '\033') { // if the first value is esc
    getch(); // skip the [
    switch(getch()) { // the real value
        case 'A':
            // code for arrow up
            break;
        case 'B':
            // code for arrow down
            break;
        case 'C':
            // code for arrow right
            break;
        case 'D':
            // code for arrow left
            break;
    }
}
查看更多
We Are One
3楼-- · 2019-01-05 02:18

for a solution that uses ncurses with working code and initialization of ncurses see getchar() returns the same value (27) for up and down arrow keys

查看更多
疯言疯语
4楼-- · 2019-01-05 02:18
    void input_from_key_board(int &ri, int &ci)
{
    char ch = 'x';
    if (_kbhit())
    {
        ch = _getch();
        if (ch == -32)
        {
            ch = _getch();
            switch (ch)
            {
            case 72: { ri--; break; }
            case 80: { ri++; break; }
            case 77: { ci++; break; }
            case 75: { ci--; break; }

            }
        }
        else if (ch == '\r'){ gotoRowCol(ri++, ci -= ci); }
        else if (ch == '\t'){ gotoRowCol(ri, ci += 5); }
        else if (ch == 27) { system("ipconfig"); }
        else if (ch == 8){ cout << " "; gotoRowCol(ri, --ci); if (ci <= 0)gotoRowCol(ri--, ci); }
        else { cout << ch; gotoRowCol(ri, ci++); }
        gotoRowCol(ri, ci);
    }
}
查看更多
相关推荐>>
5楼-- · 2019-01-05 02:18

how about trying this?

void CheckKey(void) {
int key;
if (kbhit()) {
    key=getch();
    if (key == 224) {
        do {
            key=getch();
        } while(key==224);
        switch (key) {
            case 72:
                printf("up");
                break;
            case 75:
                printf("left");
                break;
            case 77:
                printf("right");
                break;
            case 80:
                printf("down");
                break;
        }
    }
    printf("%d\n",key);
}

int main() {
    while (1) {
        if (kbhit()) {
            CheckKey();
        }
    }
}

(if you can't understand why there is 224, then try running this code: )

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

int main() {
    while (1) {
        if (kbhit()) {
            printf("%d\n",getch());
        }
    }
}

but I don't know why it's 224. can you write down a comment if you know why?

查看更多
聊天终结者
6楼-- · 2019-01-05 02:20

The keypad will allow the keyboard of the user's terminal to allow for function keys to be interpreted as a single value (i.e. no escape sequence).

As stated in the man page:

The keypad option enables the keypad of the user's terminal. If enabled (bf is TRUE), the user can press a function key (such as an arrow key) and wgetch returns a single value representing the function key, as in KEY_LEFT. If disabled (bf is FALSE), curses does not treat function keys specially and the program has to interpret the escape sequences itself. If the keypad in the terminal can be turned on (made to transmit) and off (made to work locally), turning on this option causes the terminal keypad to be turned on when wgetch is called. The default value for keypad is false.

查看更多
爱情/是我丢掉的垃圾
7楼-- · 2019-01-05 02:21

getch () function returns two keycodes for arrow keys (and some other special keys), as mentioned in the comment by FatalError. It returns either 0 (0x00) or 224 (0xE0) first, and then returns a code identifying the key that was pressed.

For the arrow keys, it returns 224 first followed by 72 (up), 80 (down), 75 (left) and 77 (right). If the num-pad arrow keys (with NumLock off) are pressed, getch () returns 0 first instead of 224.

Please note that getch () is not standardized in any way, and these codes might vary from compiler to compiler. These codes are returned by MinGW and Visual C++ on Windows.

A handy program to see the action of getch () for various keys is:

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

int main ()
{
    int ch;

    while ((ch = _getch()) != 27) /* 27 = Esc key */
    {
        printf("%d", ch);
        if (ch == 0 || ch == 224)
            printf (", %d", _getch ()); 
        printf("\n");
    }

    printf("ESC %d\n", ch);

    return (0);
}

This works for MinGW and Visual C++. These compilers use the name _getch () instead of getch () to indicate that it is a non-standard function.

So, you may do something like:

ch = _getch ();
if (ch == 0 || ch == 224)
{
    switch (_getch ())
    {
        case 72:
            /* Code for up arrow handling */
            break;

        case 80:
            /* Code for down arrow handling */
            break;

        /* ... etc ... */
    }
}
查看更多
登录 后发表回答