teclado - getch y códigos de flecha
tecla flecha c++ (10)
Estoy escribiendo un programa 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!
¿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 <stdio.h>
#include <conio.h>
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é?
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;
}
}
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 programa 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 programador solo quiere mover 4 líneas.
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 !
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;
}
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 compilador a compilador. Estos códigos son devueltos por MinGW y Visual C ++ en Windows.
Un programa útil para ver la acción de getch () para varias teclas 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.
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 ... */
}
}
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)
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
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);
}
}