2012-05-05 44 views
27

Estoy escribiendo un programa que usa getch() para buscar claves de flecha. Mi código hasta ahora es:getch y códigos de flecha

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 pulso 'A', 'B', 'C' o 'D' el código también será ejecutada, porque 65 es el código decimal para 'A', etc ...

Es Hay una forma de comprobar si hay una tecla de flecha sin llamar a los demás?

Gracias!

+1

Han pasado años desde que jugué con esto, no está ni un poco estandarizado ... pero cuando jugué con 'getch()', para las teclas "especiales" volvía dos veces. La primera vez que devolvió un 0, luego un código para la clave especial, para que pueda diferenciarlo de otras teclas. – FatalError

+0

'65' es solo para el carácter' A'. Debes usar los códigos de control para recibir estas claves. Ver esta publicación http://stackoverflow.com/questions/2876275/what-are-the-ascii-values-of-up-down-left-right –

Respuesta

48

pulsando una tecla de flecha getch empujará tres valores en la memoria intermedia:

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

Así que 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; 
    } 
} 
+1

¿Hay alguna versión Unix-land de 'getch' donde esta respuesta es correcta? Los códigos aquí son lo que obtendrías de la mayoría de las terminales cuando usas 'getchar'. No son lo que obtendrías de 'getch' from' '. –

+1

'case 'A'' debe ser' case' A ': ', también para' case' D'' – Nik

+0

¿Sabes por qué en mi terminal veo una 'O' en vez de '[' como segundo personaje? FYI, estoy ejecutando zsh dentro de una sesión de tmux. ¡Gracias! – Muffo

15

getch() la función 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, devuelve 224 primero seguido de 72 (arriba), 80 (abajo), 75 (izquierda) y 77 (derecha). Si se pulsan las teclas de flecha pad numérico (con Bloq Num apagado), getch() devuelve 0 primera vez de 224.

Tenga en cuenta que getch() no ha sido estandarizada de ninguna manera, y estos códigos puede variar de un compilador compilador. Estos códigos son devueltos por MinGW y Visual C++ en Windows.

un programa práctico para ver la acción de getch() para varias claves es:

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

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

Por lo tanto, es posible 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 ... */ 
    } 
} 
1

Así, después de un montón de lucha, he resuelto este problema milagrosamente everannoying! Estaba tratando de 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 un poco audaz pero explica mucho. Buena suerte !

1

En realidad, para leer las teclas de flecha es necesario leer su código de exploración. Los siguientes son el código de exploración generada por las flechas de prensa (no liberación de tecla)

Cuando bloq num está desactivado

  • izquierda E0 4B
  • derecho E0 4D
  • Hasta E0 48
  • Abajo E0 50

Cuando Bloq Num está activado estas teclas conseguir precedido con E0 2A

  • Byte E0 es -32
  • Byte 48 es de 72 UP
  • Byte 50 es 80 ABAJO

    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 abo Como he supuesto, el programador quiere mover solo 4 líneas.

+0

¿Podría explicar su respuesta, por favor? –

1

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 de teclado permite que el teclado del terminal del usuario. Si habilitado (bf es VERDADERO), el usuario puede presionar una tecla de función (como una flecha ) y wgetch devuelve un único valor que representa la función clave, como en KEY_LEFT. Si está deshabilitado (bf es FALSE), curses no trata las teclas de función especialmente y el programa tiene que interpretar las secuencias de escape . Si el teclado en el terminal se puede encender (se hizo para transmitir) y apagado (hecho para trabajar localmente), al activar esta opción se activa el teclado del terminal cuando se llama a wgetch. El valor predeterminado para el teclado es falso.

0

He escrito una función utilizando getch para obtener el código de flecha. es una solución quick'n'dirty pero la función devolverá un código ASCII en función de tecla de flecha: UP: -10 ABAJO: -11 DERECHA: -12 IZQUIERDA: -13

Por otra parte, con esta función , podrás diferenciar el toque de ESCAPAR 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; 
} 
0

Soy apenas un motor de arranque, pero i'v creado un char(for example "b"), y lo hago b = _getch(); (comando es una biblioteca de conio.h) y comprobar

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

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