Pregunta

Posibles Duplicados:
Lo que es equivalente a getch() & getche() en Linux?

Soy un novato en linux de programación.:-)

Me pregunto si mi programa (usando C el lenguaje) puede capturar cada golpe de tecla inmediatamente en linux, y luego decidir si echo o no, y cómo mostrar, al igual que telnet.

por ejemplo, si un usuario golpea 'A', quiero el programa para mostrar 'B', si los tipos de 'B', 'C' que se quiere, y así sucesivamente.

Suena gracioso e inútil.Sólo estoy curioso acerca de ella.

¿Fue útil?

Solución

Básicamente, depende en gran medida de cómo se definen de inmediato.

Hay dos tareas aquí. El primero es deshabilitar el eco de la llave regular que está integrado en la mayoría de las bibliotecas de entrada C. El segundo es imprimir el nuevo carácter en lugar del anterior.

en el código pseudo.

 echo(off);
 while (capturing && charIsAvailable()) {
   c = readOneChar();
   if (c == '\n') {
     capturing = false;
   }
   printf("%c", c++);
 }
 echo(on);

Hay una serie de sistemas que se comunican para capturar una pulsación de teclas.

  1. el teclado
  2. (posiblemente) un bus USB
  3. el controlador de interrupciones de la CPU
  4. el sistema operativo
  5. El proceso de X Window Server
  6. la ventana x "que tiene enfocamiento.
  7. El último paso se realiza con un programa que ejecuta un bucle continuo que captura eventos del servidor X y los procesa. Si desea expandir este programa de ciertas maneras (obtenga el tiempo que se presionó la clave), debe informar a los otros programas que desea eventos de teclado "RAW", lo que significa que realmente no recibirá completamente "Cocinado " caracteres. Como resultado, tendrá que hacer un seguimiento de qué teclas están arriba y abajo, y cuánto tiempo, y manejar todo el comportamiento de la clave meta impar en su programa (eso no es un 'a' es un 'A' porque cambia está abajo, etc.).

    También hay otros modos de procesamiento a considerar, como canónicos y no canónicos, lo que controlará si desea que los eventos se reciban en trozos orientados a la línea (eventos de línea) o trozos orientados a los personajes (eventos de caracteres). Nuevamente, esto es algo complicado por la necesidad de informar a los programas ascendentes sobre los requisitos del cliente más abajo.

    Ahora que tiene una idea de su entorno, visite el código real necesario para suprimir la salida de caracteres.

    // define a terminal configuration data structure
    struct termios term;
    
    // copy the stdin terminal configuration into term
    tcgetattr( fileno(stdin), &term );
    
    // turn off Canonical processing in term
    term.c_lflag &= ~ICANON;
    
    // turn off screen echo in term
    term.c_lflag &= ~ECHO;
    
    // set the terminal configuration for stdin according to term, now
    tcsetattr( fileno(stdin), TCSANOW, &term);
    
    
    (fetch characters here, use printf to show whatever you like)
    
    // turn on Canonical processing in term
    term.c_lflag |= ICANON;
    
    // turn on screen echo in term
    term.c_lflag |= ECHO;
    
    // set the terminal configuration for stdin according to term, now
    tcsetattr( fileno(stdin), TCSANOW, &term);
    

    Incluso esto no es inmediato. Para obtener inmediato, debe acercarse a la fuente, que eventualmente significa un módulo de kernel (que aún no es tan inmediato como el micro controlador del teclado, que no es tan inmediato como el momento en que se cierra el interruptor). Con suficientes artículos entre la fuente y el destino, eventualmente se vuelve posible notar la diferencia, sin embargo, en la práctica, las personas que buscan la mejor compensación entre el rendimiento y la flexibilidad.

Otros consejos

Edwin Buck proporciona una gran respuesta.Aquí es otra alternativa que se utiliza ncurses que hace las cosas un poco más fácil y es compatible con casi todas las distribuciones de Linux y otras variantes de Unix.

#include <ncurses.h>

int main(int argc, char *argv[])
{
    int ch,c;
    initscr();
    cbreak();
    noecho();

    while( ch != 'q')
    {
        switch( c = getch() )
        {
            case 'a':
                ch = 'b';
            break;

            case 'b':
                ch = 'c';
            break;

            case 'c':
                ch = 'd';
            break;

            default:
                ch = c;                 
            break;
        }
        printw("%c",ch);
    }
    endwin();
    return(0);
}

compilar con gcc código.c-o código -lncurses

Y aquí están algunas de vínculos de apoyo:

ncurses noecho y otros - página man
ncurses programación HOWTO

Este código se puede encontrar en el internet y es por kermi3 de c-board

#include <termios.h>
#include <unistd.h>

int mygetch(void)
{
    struct termios oldt,newt;
    int ch;
    tcgetattr( STDIN_FILENO, &oldt );
    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newt );
    ch = getchar();
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
    return ch;
}

EDITAR: por supuesto que si usted desea conseguir el char en sí y no el valor ascii de cambio a char en lugar de int

Puede ser excesivo, pero puede usar bibliotecas de juego como sdl para lograr eso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top