web-dev-qa-db-fra.com

codes getch et arrow

J'écris un programme qui utilise getch() pour rechercher les touches de direction. Mon code jusqu'ici est:

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

Le problème est que lorsque j'appuie sur 'A', 'B', 'C' ou 'D', le code sera également exécuté, car 65 est le code décimal pour 'A', etc.

Existe-t-il un moyen de rechercher une touche de direction sans appeler les autres?

Merci!

33
qwertz

En appuyant sur une des touches de direction getch va insérer trois valeurs dans la mémoire tampon:

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

Donc, le code ressemblera à ceci:

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;
    }
}
54
qwertz

la fonction getch () renvoie deux codes clés pour les touches de direction (et quelques autres touches spéciales), comme indiqué dans le commentaire de FatalError. Il renvoie d'abord 0 (0x00) ou 224 (0xE0), puis renvoie un code identifiant la touche sur laquelle vous avez appuyé.

Pour les touches fléchées, il renvoie 224 en premier suivi de 72 (en haut), 80 (en bas), 75 (à gauche) et 77 (à droite). Si vous appuyez sur les touches fléchées du pavé numérique (avec le verrouillage numérique), getch () renvoie 0 en premier au lieu de 224.

Notez que getch () n'est en aucun cas normalisé et que ces codes peuvent varier d'un compilateur à l'autre. Ces codes sont renvoyés par MinGW et Visual C++ sous Windows.

Un programme pratique pour voir l'action de getch () pour différentes clés est:

#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);
}

Cela fonctionne pour MinGW et Visual C++. Ces compilateurs utilisent le nom _getch () au lieu de getch () pour indiquer qu'il s'agit d'une fonction non standard.

Donc, vous pouvez faire quelque chose comme:

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 ... */
    }
}
18

En fait, pour lire les touches fléchées, il est nécessaire de lire son code de numérisation . Les codes de numérisation générés par les touches fléchées sont les suivants (non relâchées).

Lorsque le verrouillage numérique est désactivé

  • Gauche E0 4B 
  • Droite E0 4D 
  • Jusqu'à E0 48 
  • Down E0 50

Lorsque Num Lock est activé, ces touches sont précédées de E0 2A

  • Octet E0 est -32
  • L'octet 48 est 72 UP
  • L'octet 50 est 80 en bas

    user_var=getch();
    if(user_var == -32)
    {
        user_var=getch();
        switch(user_var)
        {
        case 72:
            cur_sel--;
            if (cur_sel==0)
                cur_sel=4;
            break;
        case 80:
            cur_sel++;
            if(cur_sel==5)
                cur_sel=1;
            break;
    
        }
    }
    

Dans le code ci-dessus, j'ai supposé que le programmeur veut déplacer 4 lignes seulement.

2
Shubham

Donc, après beaucoup de lutte, j'ai miraculeusement résolu ce problème qui ne cessait jamais de bouleverser! J'essayais de mimer un terminal Linux et de rester bloqué à la partie où il conserve un historique des commandes accessible en appuyant sur les touches fléchées haut/bas. J'ai trouvé que ncurses lib était pénible, difficile à comprendre et lent à apprendre.

char ch = 0, k = 0;
while(1)
{
  ch = getch();
  if(ch == 27)                  // if ch is the escape sequence with num code 27, k turns 1 to signal the next
    k = 1;
  if(ch == 91 && k == 1)       // if the previous char was 27, and the current 91, k turns 2 for further use
    k = 2;
  if(ch == 65 && k == 2)       // finally, if the last char of the sequence matches, you've got a key !
    printf("You pressed the up arrow key !!\n");
  if(ch == 66 && k == 2)                             
    printf("You pressed the down arrow key !!\n");
  if(ch != 27 && ch != 91)      // if ch isn't either of the two, the key pressed isn't up/down so reset k
    k = 0;
  printf("%c - %d", ch, ch);    // prints out the char and it's int code

C'est un peu audacieux mais cela explique beaucoup. Bonne chance !

2
kundrata

Le keypad permettra au clavier du terminal de l'utilisateur de permettre l'interprétation des touches de fonction comme une valeur unique (c'est-à-dire, aucune séquence d'échappement).

Comme indiqué dans la page de manuel:

L'option clavier active le clavier du terminal de l'utilisateur. Si activé (bf est VRAI), l'utilisateur peut appuyer sur une touche de fonction (telle qu'une touche fléchée ) et wgetch renvoie une valeur unique représentant la fonction comme dans KEY_LEFT. Si désactivé (bf est FALSE), les malédictions ne traitent pas touches de fonction spécialement et le programme doit interpréter l'échappement séquences lui-même. Si le clavier du terminal peut être activé (configuré pour transmettre) et désactivé (conçu pour fonctionner localement), activez cette option provoque l’activation du clavier du terminal lors de l’appel de wgetch. Le La valeur par défaut du clavier est false.

1
tijko

que diriez-vous d'essayer cela?

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();
        }
    }
}

(Si vous ne comprenez pas pourquoi il y en a 224, essayez de lancer ce code:)

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

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

mais je ne sais pas pourquoi c'est 224. pouvez-vous écrire un commentaire si vous savez pourquoi?

Je suis juste un démarreur, mais j'ai créé une char(for example "b"), et je fais b = _getch(); (c'est une commande de conio.h library)

If (b == -32)
b = _getch();

Et vérifiez les clés (72 en haut, 80 en bas, 77 à droite, 75 à gauche)

0
Ant Redstone

pour une solution qui utilise ncurses avec un code de travail et l'initialisation de ncurses, voir getchar () renvoie la même valeur (27) pour les touches fléchées haut et bas

0
ralf htp
    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);
    }
}
0
Malik fawad01

J'ai écrit une fonction en utilisant getch pour obtenir le code de la flèche. c'est une solution rapide mais la fonction retournera un code ASCII dépendant de la touche fléchée: : -13

De plus, avec cette fonction, vous pourrez différencier les touches ESCAPE et les touches fléchées. Mais vous devez appuyer sur ESC 2 fois pour activer la touche ESC.

voici le code: 

char getch_hotkey_upgrade(void)
{
  char ch = 0,ch_test[3] = {0,0,0};

    ch_test[0]=getch();

    if(ch_test[0] == 27)
    {
        ch_test[1]=getch();

        if (ch_test[1]== 91)
        {
            ch_test[2]=getch();

            switch(ch_test[2])
            {
            case 'A':
                //printf("You pressed the up arrow key !!\n");
                //ch = -10;
                ch = -10;
                break;
            case 'B':
                //printf("You pressed the down arrow key !!\n");
                ch = -11;
                break;
            case 'C':
                //printf("You pressed the right arrow key !!\n");
                ch = -12;
                break;
            case 'D':
                //printf("You pressed the left arrow key !!\n");
                ch = -13;
                break;
            }
        }
        else
         ch = ch_test [1];
    }
    else
        ch = ch_test [0];
  return ch;
}
0
Thomas Broussard