Estoy usando la consola Linux y me gustaría hacer un programa que muestre caracteres aleatorios hasta que se presione ESC. ¿Cómo puedo hacer un controlador de teclado?¿Cómo se maneja la tecla presionada en una consola Linux en C?
Respuesta
getch() de Curses library maybe? Además, deberá usar notimeout() para indicarle a getch() que no espere la siguiente pulsación de tecla.
Debe explícitamente hablar de que estamos hablando de la (N) maldice biblioteca. –
Sí, claro. Actualizado. Gracias. –
nota: getch() de ncurses necesita una "pantalla" de ncurses adecuada para ser inicializada, o no funcionará. – ShinTakezou
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
char * me = "Parent";
void sigkill(int signum)
{
//printf("=== %s EXIT SIGNAL %d ===\n", me, signum);
exit(0);
}
main()
{
int pid = fork();
signal(SIGINT, sigkill);
signal(SIGQUIT, sigkill);
signal(SIGTERM, sigkill);
if(pid == 0) //IF CHILD
{
int ch;
me = "Child";
while(1)
{
ch = (rand() % 26) + 'A'; // limit range to ascii A-Z
printf("%c",ch);
fflush(stdout); // flush output buffer
sleep(2); // don't overwhelm
if (1 == getppid())
{
printf("=== CHILD EXIT SINCE PARENT DIED ===\n");
exit(0);
}
}
printf("==CHILD EXIT NORMAL==\n");
}
else //PARENT PROCESS
{
int ch;
if((ch = getchar())==27)
kill(pid, SIGINT);
//printf("==PARENT EXIT NORMAL (ch=%d)==\n", ch);
}
return(0);
}
En este programa u sólo tendrá que pulsar enter
después esc
char, porque getchar()
es una función de bloqueo. También puede eliminar o disminuir el tiempo de inactividad del proceso hijo según lo necesite.
Excepto que 'getchar' espera la entrada, por lo que no se generarán caracteres aleatorios mientras' getchar' espera a que el usuario presione [enter]. –
cambio de los ajustes de TTY para una pulsación de tecla:
int getch(void) {
int c=0;
struct termios org_opts, new_opts;
int res=0;
//----- store old settings -----------
res=tcgetattr(STDIN_FILENO, &org_opts);
assert(res==0);
//---- set new terminal parms --------
memcpy(&new_opts, &org_opts, sizeof(new_opts));
new_opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOKE | ICRNL);
tcsetattr(STDIN_FILENO, TCSANOW, &new_opts);
c=getchar();
//------ restore old settings ---------
res=tcsetattr(STDIN_FILENO, TCSANOW, &org_opts);
assert(res==0);
return(c);
}
¿No 'ICRNL' entra en el campo 'c_iflag', no en el campo' c_lflag'? –
La disciplina de línea de un equipo terminal a menudo funciona en el modo canónico de manera predeterminada. En este modo, el controlador del terminal no presenta el búfer en el espacio de usuario hasta que se ve la nueva línea (). Se ingresa la clave).
Puede configurar el terminal en modo raw (no canónico) utilizando tcsetattr()
para manipular la estructura termios
. Al borrar los indicadores ECHO
y ICANON
, se deshabilita el eco de caracteres a medida que se escriben y hace que las solicitudes de lectura se satisfagan directamente desde la cola de entrada. Establecer los valores de VTIME
y VMIN
en cero en la matriz c_cc
hace que la solicitud de lectura (fgetc()
) vuelva inmediatamente en lugar de bloquearse; efectivamente encuestando stdin. La llamada al fgetc()
devolverá EOF
si un carácter no está disponible en la transmisión.
#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <time.h>
int getkey() {
int character;
struct termios orig_term_attr;
struct termios new_term_attr;
/* set the terminal to raw mode */
tcgetattr(fileno(stdin), &orig_term_attr);
memcpy(&new_term_attr, &orig_term_attr, sizeof(struct termios));
new_term_attr.c_lflag &= ~(ECHO|ICANON);
new_term_attr.c_cc[VTIME] = 0;
new_term_attr.c_cc[VMIN] = 0;
tcsetattr(fileno(stdin), TCSANOW, &new_term_attr);
/* read a character from the stdin stream without blocking */
/* returns EOF (-1) if no character is available */
character = fgetc(stdin);
/* restore the original terminal attributes */
tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
return character;
}
int main()
{
int key;
/* initialize the random number generator */
srand(time(NULL));
for (;;) {
key = getkey();
/* terminate loop on ESC (0x1B) or Ctrl-D (0x04) on STDIN */
if (key == 0x1B || key == 0x04) {
break;
}
else {
/* print random ASCII character between 0x20 - 0x7F */
key = (rand() % 0x7F);
printf("%c", ((key < 0x20) ? (key + 0x20) : key));
}
}
return 0;
}
Nota: Este código omite la comprobación de errores por simplicidad.
Parece que funciona, pero también parece proporcionar todo el búfer cada vez. Entonces, si presiono aa, entonces b, luego c, después de presionar c, muestra aababc – Jackie
@Jackie, tal vez haga un 'while (getchar()! = EOF);' después de 'character = fgetc (stdin);' –
- 1. ¿Cómo se escribe "ingresar la tecla presionada" en una secuencia?
- 2. ¿Cómo evito que se imprima la tecla presionada en la consola en .NET?
- 3. ¿Cómo leer una tecla presionada por el usuario y mostrarla en la consola?
- 4. Se mantiene presionada la tecla shift en JavaScript
- 5. ¿Está presionada la tecla 'Ctrl'?
- 6. Diferenciar entre tecla presionada y tecla mantenida
- 7. ¿Cómo puedo escuchar una tecla TAB presionada/tipada en Java?
- 8. ¿Cómo comprobar si la tecla presionada era una tecla de flecha en Java KeyListener?
- 9. Pruebe si la tecla Ctrl está presionada con C#
- 10. Averigüe la tecla presionada de carácter
- 11. Cómo atrapar una tecla presionada en un formulario de C# .NET
- 12. Cómo hago para que python espere una tecla presionada
- 13. Cómo verificar si la tecla se mantiene presionada durante el inicio en Java
- 14. ¿Cómo obtengo el valor de cada tecla presionada y la uso en una variable con jQuery?
- 15. C# - Detectando si se mantiene presionada la tecla al abrir un menú contextual
- 16. ¿Cómo puedo determinar cuándo se mantiene presionada la tecla de control durante el clic del botón
- 17. Tecla de captura presionada con el teclado virtual en Android?
- 18. ¿Cómo puedo hacer que un sprite se mueva cuando se mantiene presionada la tecla
- 19. ¿Cómo se maneja la finalización determinística en C#?
- 20. Cómo deshabilitar la tecla repetitiva en jQuery
- 21. Comprobando si se presionó alguna tecla en la aplicación de consola C#
- 22. ¿Cómo se manejan los eventos de pulsación de tecla en una aplicación de la consola Qt?
- 23. Entrada de la tecla de flecha C# para una aplicación de consola
- 24. Enviar formulario cuando ingrese la tecla presionada con Prototype javascript
- 25. Capturar una tecla Intro presionada en cualquier lugar de la página
- 26. ¿Cómo se maneja la concurrencia en NHibernate?
- 27. Cómo convertir una tecla Intro Pulse en una pestaña Presione la tecla para páginas web
- 28. ¿Cómo detectar la tecla de escape presionada cuando está en un video de Youtube?
- 29. Cómo obtener el valor de la tecla presionada de un objeto de evento en jQuery
- 30. ¿Cómo capturar la tecla Intro presionada en las páginas que contienen varias formas?
similar y/o relacionados - [C sin bloqueo de entrada de teclado] (http://stackoverflow.com/q/448944/203667) – jschmier