getch y códigos de flecha

Estoy escribiendo un progtwig que está usando getch() para buscar claves de flecha. Mi código hasta ahora es:

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

El problema es que cuando presiono 'A' , 'B' , 'C' o 'D' el código también se ejecutará, porque 65 es el código decimal para 'A' , etc.

¿Hay alguna manera de verificar una flecha sin llamar a otros?

¡Gracias!

Al presionar una tecla de flecha, getch presionará tres valores en el búfer:

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

Entonces el código será algo como esto:

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

La función getch () devuelve dos códigos de tecla para las teclas de flecha (y algunas otras teclas especiales), como se menciona en el comentario de FatalError. Devuelve 0 (0x00) o 224 (0xE0) primero, y luego devuelve un código que identifica la tecla que se presionó.

Para las teclas de flecha, vuelve 224 primero seguido por 72 (arriba), 80 (abajo), 75 (izquierda) y 77 (derecha). Si se presionan las teclas de flecha num-pad (con NumLock desactivado), getch () devuelve 0 primero en lugar de 224.

Tenga en cuenta que getch () no está estandarizado de ninguna manera, y estos códigos pueden variar de comstackdor a comstackdor. Estos códigos son devueltos por MinGW y Visual C ++ en Windows.

Un progtwig útil para ver la acción de getch () para varias teclas es:

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

Esto funciona para MinGW y Visual C ++. Estos comstackdores usan el nombre _getch () en lugar de getch () para indicar que es una función no estándar.

Entonces, puedes hacer algo como:

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

Entonces, después de mucha lucha, ¡resolví milagrosamente este tema tan vistoso! Intenté imitar un terminal de Linux y me quedé atrapado en la parte donde guarda un historial de comandos al que se puede acceder presionando las teclas de flecha hacia arriba o hacia abajo. Descubrí que ncurses lib es dolorosamente difícil de comprender y lento para aprender.

 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 

Es algo audaz pero explica mucho. Buena suerte !

El keypad permitirá que el teclado del terminal del usuario permita que las teclas de función se interpreten como un único valor (es decir, sin secuencia de escape).

Como se indica en la página del manual:

La opción del teclado habilita el teclado del terminal del usuario. Si está habilitado (bf es VERDADERO), el usuario puede presionar una tecla de función (como una tecla de flecha) y wgetch devuelve un único valor que representa la tecla de función, como en KEY_LEFT. Si está desactivado (bf es FALSE), curses no trata especialmente las teclas de función y el progtwig tiene que interpretar las secuencias de escape en sí. Si el teclado en el terminal se puede encender (hacer para transmitir) y apagar (hacer que funcione localmente), activar esta opción hace que el teclado del terminal se encienda cuando se llama a wgetch. El valor predeterminado para el teclado es falso.

En realidad, para leer las teclas de flecha uno necesita leer su código de exploración. A continuación se muestra el código de exploración generado por las teclas de flecha presione (no liberación de tecla)

Cuando Bloq num está desactivado

  • Izquierda E0 4B
  • Derecha E0 4D
  • Up E0 48
  • Abajo E0 50

Cuando Num Lock está activado, estas teclas van precedidas por E0 2A

  • Byte E0 es -32
  • Byte 48 es 72 UP
  • Byte 50 es 80 DOWN

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

En el código anterior he supuesto que el progtwigdor solo quiere mover 4 líneas.

para una solución que utiliza ncurses con código de trabajo e inicialización de ncurses, ver getchar () devuelve el mismo valor (27) para las teclas de flecha arriba y abajo

He escrito una función usando getch para obtener el código de flecha. Es una solución rápida y sucia, pero la función devolverá un código ASCII según la tecla de flecha: ARRIBA: -10 ABAJO: -11 DERECHA: -12 IZQUIERDA: -13

Además, con esta función, podrá diferenciar el toque de ESCAPE y las teclas de flecha. Pero debe presionar ESC 2 veces para activar la tecla ESC.

aquí el código:

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

Solo soy un principiante, pero he creado un char(for example "b") y hago b = _getch(); (es un conio.h biblioteca conio.h ) Y verifique

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

Y verifique las claves (72 arriba, 80 abajo, 77 derecha, 75 izquierda)

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

¿Qué hay de intentar esto?

 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 no puede entender por qué hay 224, intente ejecutar este código)

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

pero no sé por qué es 224. ¿puedes escribir un comentario si sabes por qué?