elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Entrar al Canal Oficial Telegram de elhacker.net


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  ayuda con kbhit()
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: ayuda con kbhit()  (Leído 4,780 veces)
0xDani


Desconectado Desconectado

Mensajes: 1.077



Ver Perfil
ayuda con kbhit()
« en: 19 Mayo 2012, 17:08 pm »

Hola bueno veran he estado buscando como emular la funcion kbhit() de conio.h en ubuntu, yhe encontrado referencias a curses y ncurses, ademas en este foro me las han recomendado, pero no encuentro la forma de emular esta funcion, agradeceria mucho ayuda. :huh:

Saludos :D


En línea

I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM
RyogiShiki


Desconectado Desconectado

Mensajes: 745


げんしけん - Hikkikomori FTW!!!


Ver Perfil WWW
Re: ayuda con kbhit()
« Respuesta #1 en: 19 Mayo 2012, 19:39 pm »

Hola.

Bueno, hacia bastante tiempo no tocaba a ncurses, buscando un poco he encontrado un ejemplo en StackOverflow que emula la función kbhit() y como veo que no conoces aun ncurses, pues paso a explicar el ejemplo:

Código
  1. #include <ncurses.h>
  2. #include <unistd.h>  /* only for sleep() */
  3.  
  4. int kbhit(void)
  5. {
  6.    int ch = getch();
  7.  
  8.    if (ch != ERR) {
  9.        ungetch(ch);
  10.        return 1;
  11.    } else {
  12.        return 0;
  13.    }
  14. }
  15.  
  16. int main(void)
  17. {
  18.    initscr();
  19.  
  20.    cbreak();
  21.    noecho();
  22.    nodelay(stdscr, TRUE);
  23.  
  24.    scrollok(stdscr, TRUE);
  25.    while (1) {
  26.        if (kbhit()) {
  27.            printw("Key pressed! It was: %d\n", getch());
  28.            refresh();
  29.        } else {
  30.            printw("No key pressed yet...\n");
  31.            refresh();
  32.            sleep(1);
  33.        }
  34.    }
  35. }

El principio del programa:
Código
  1. #include <ncurses.h>
  2. #include <unistd.h>  /* only for sleep() */
incluimos como no ncurses que es la que nos va a permitir interactuar y generar respuesta a las acciones del teclado. Incluimos también unistd que nos da accceso a la API POSIX del sistema, aunque en este caso solo vamos usar como se ve en el omentario la función sleep()

Bueno, empecemos por la función main antes de ir a la función kbhit:

Código
  1. initscr();
Esta función es la que va a inicializar el modo curses ni no llamamos a esta función no podremos usar el resto de ncurses.

Código
  1. cbreak();
Esta función deshabilita el "line buffering" del terminal, lo que quiere decir que no es necesario hacer retorno de carro o tener un caracter de nueva linea al final, sino que los caracteres que tipeamos en el teclado son enviados directamente.

Código
  1. noecho();
esta función deshabilita el "eco" del terminal, lo que significa que los caracteres que se ingresan no son mostrados, similar a cuando se ingresa una contraseña desde la terminal.

Código
  1. nodelay(stdscr, TRUE);
esta función convierte a la función getch() en una llamada no bloqueante, lo que quiere decir que cuando se usa getch() el programa no se va a parar a esperar a que el usuario ingrese algo, si no se ingresa nada entonces la función devuelve ERR y si se ingresa algo entonces almacena el código de la tecla que fue ingresada. Esta función acepta dos parámetros stdscr y la representación de un booleano (TRUE o FALSE). Verás cuando se trabaja con ncurses se usa el concepto de WINDOWS que no son nada más que espacios independientes en donde se puede disponer de la información que queramos que el usuario conozca, igualmente podemos cerrar eliminar o crear nuevas WINDOW. por defecto ncurses establece que la ventana principal es stdscr. Entonces en definitiva lo que hacemos con la función es decir que queremos que getch no sea bloqueante unicamente en stdscr si tuviéramos otras WINDOWS no serian afectadas por esta función, y por supuesto para deshabilitar con un simple nodelay(stdscr, FALSE).

Código
  1. scrollok(stdscr, TRUE);
VA a evitar que se presente scroll fuera de los limites del tamaño actual de la terminal, osea que verás que el buffer de lo que se muestra en pantalla no se almacena y nunca habrá scroll, como lo explique antes esto se aplica a stdscr y para deshabilitar con scrollok(stdscr, FALSE);

Antes de continuar a revisar el loop revisemos la función kbhit:
Código
  1. int kbhit(void)
  2. {
  3.    int ch = getch();
  4.  
  5.    if (ch != ERR) {
  6.        ungetch(ch);
  7.        return 1;
  8.    } else {
  9.        return 0;
  10.    }
  11. }
  12.  
Entonces vemos que es una función que retorna un entero, en este caso 1 o 0 y no recibe ningún parámetro. Estamos almacenando lo que retorna getch() en ch, para el momento en el que llamemos a kbhit() getch no debería ser bloqueante. comprobamos si ch es diferente de ERR, entonces se habrá producido una pulsación, pero cuando llamamos a getch el código de la tecla habrá sido sacada de la cola de entrada, lo cual es un problema, así que para devolverla hacemos un ungetch(ch), así la próxima vez que llamemos a getch() nos devolvera el código de la tecla que estaba en ch. Si recibimos ERR no habrá pulsación alguna y retornamos 0.

Ahora al bucle:
Código
  1. while (1) {
  2.        if (kbhit()) {
  3.            printw("Key pressed! It was: %d\n", getch());
  4.            refresh();
  5.        } else {
  6.            printw("No key pressed yet...\n");
  7.            refresh();
  8.            sleep(1);
  9.        }
  10.    }
  11.  

Entonces comenzamos un bucle infinito, y probamos el retorno de kbhit, si kbhit retorna 1 entonces habrá una pulsación, imprimimos que se ha presentado una pulsación y obtenemos el código que estará en getch() (gracias a ungetch()), así si presionamos la tecla 'a' por ejemplo tendremos una salida como la siguiente:
Citar
Key pressed! It was: 97
donde 97 es el código ASCII de 'a'

Si kbhit devuelve 0 entonces no habrá pulsación y tendremos una salida como la siguiente:
Citar
No key pressed yet...

Código
  1. refresh()
ncurses nos permite reducir la latencia del terminal. Si queremos que los cambios que hemos hecho se muestren por pantalla es neesario usar refresh, si no lo hacemos no se mostrará ningún cambio que se haya producido (en este caso en stdscr).

Código
  1. sleep(1)
finalmente para poder ver que es lo que estamos haciendo, y no tener un loop loco en la pantalla dormimos el programa por 1 segundo, tiempo más que suficiente para ver que es lo que sucede.

Ahora creo que estás en ubuntu, así que lo primero es instalar la librería ncurses para desarrollo y si no estoy mal sería:
Código
  1. sudo apt-get install ncurses-dev

Luego para compilar usamos el siguiente comando:
Código
  1. gcc code.c -o code -lncurses

y para ejecutar y ver el resultado:
Código
  1. ./code

Espero haya sido de ayuda.

Saludos


« Última modificación: 19 Mayo 2012, 19:59 pm por RyogiShiki » En línea

0xDani


Desconectado Desconectado

Mensajes: 1.077



Ver Perfil
Re: ayuda con kbhit()
« Respuesta #2 en: 19 Mayo 2012, 21:00 pm »

Muchas gracias, si que ha sido de mucha ayuda, me has resuelto todas mis dudas de un tiron, y ademas me has explicado el code paso a paso, que mas que dar las gracias y quitarse el sombrero;-)

En línea

I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM
RyogiShiki


Desconectado Desconectado

Mensajes: 745


げんしけん - Hikkikomori FTW!!!


Ver Perfil WWW
Re: ayuda con kbhit()
« Respuesta #3 en: 19 Mayo 2012, 21:33 pm »

Bien, me alegro que haya sido de ayuda, cualquier duda no dudes en preguntar que para eso esta la comunidad.

Saludos
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Ayuda T_T alguien sabe como usar la funcion "kbhit()"?
Programación C/C++
Ai Toi 2 11,673 Último mensaje 19 Julio 2015, 17:07 pm
por Nico01
Ayuda por davor ayuda os ruego ayuda XD (SOLUCIONADO)
Hardware
XxRekcahlExX 6 11,131 Último mensaje 24 Mayo 2010, 00:56 am
por Aprendiz-Oscuro
AYUDA!! kbhit() en linux « 1 2 »
Programación C/C++
godofredo 10 10,903 Último mensaje 6 Abril 2011, 00:45 am
por godofredo
ayuda: kbhit() en iterador en c++
Programación C/C++
Nico01 6 3,566 Último mensaje 19 Julio 2015, 16:58 pm
por Nico01
Función kbhit() y getch()
Programación C/C++
jmhr98 0 2,000 Último mensaje 13 Agosto 2018, 16:12 pm
por jmhr98
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines