GNU/Linux >> Tutoriales Linux >  >> Linux

Usando kbhit() y getch() en Linux

Si tu Linux no tiene conio.h que soporta kbhit() puede buscar aquí el código de Morgan Mattews para proporcionar kbhit() funcionalidad de manera compatible con cualquier sistema compatible con POSIX.

Como el truco para desactivar el almacenamiento en búfer a nivel de termios, también debería resolver el getchar() problema como se demuestra aquí.


El ncurses howto citado anteriormente puede ser útil. Aquí hay un ejemplo que ilustra cómo se pueden usar ncurses como el ejemplo de conio:

#include <ncurses.h>

int
main()
{
    initscr();
    cbreak();
    noecho();
    scrollok(stdscr, TRUE);
    nodelay(stdscr, TRUE);
    while (true) {
        if (getch() == 'g') {
            printw("You pressed G\n");
        }
        napms(500);
        printw("Running\n");
    }
}

Tenga en cuenta que con ncurses, el iostream el encabezado no se utiliza. Esto se debe a que mezclar stdio con ncurses puede tener resultados inesperados.

ncurses, por cierto, define TRUE y FALSE . Un ncurses correctamente configurado utilizará el mismo tipo de datos para el bool de ncurses como el compilador de C++ utilizado para configurar ncurses.


Una solución compacta basada en la respuesta de Christophe es

#include <sys/ioctl.h>
#include <termios.h>

bool kbhit()
{
    termios term;
    tcgetattr(0, &term);

    termios term2 = term;
    term2.c_lflag &= ~ICANON;
    tcsetattr(0, TCSANOW, &term2);

    int byteswaiting;
    ioctl(0, FIONREAD, &byteswaiting);

    tcsetattr(0, TCSANOW, &term);

    return byteswaiting > 0;
}

A diferencia de esa respuesta, esto no dejará la terminal en un estado extraño después de que el programa haya salido. Sin embargo, aún deja los caracteres en el búfer de entrada, por lo que la tecla que se presionó aparecerá de forma no deseada en la siguiente línea de aviso.

Una solución diferente que soluciona este problema es

void enable_raw_mode()
{
    termios term;
    tcgetattr(0, &term);
    term.c_lflag &= ~(ICANON | ECHO); // Disable echo as well
    tcsetattr(0, TCSANOW, &term);
}

void disable_raw_mode()
{
    termios term;
    tcgetattr(0, &term);
    term.c_lflag |= ICANON | ECHO;
    tcsetattr(0, TCSANOW, &term);
}

bool kbhit()
{
    int byteswaiting;
    ioctl(0, FIONREAD, &byteswaiting);
    return byteswaiting > 0;
}

El uso es el siguiente

enable_raw_mode();
// ...
if (kbhit()) ...
// ...
disable_raw_mode();
tcflush(0, TCIFLUSH); // Clear stdin to prevent characters appearing on prompt

Ahora cualquier carácter escrito entre la ejecución de la primera y la última línea no aparecerá en la terminal. Sin embargo, si sale con Ctrl+C, el terminal es dejado en un estado extraño. (Suspiro)


Linux
  1. Depurar Linux usando ProcDump

  2. Verifique el espacio en disco en Linux usando los comandos df y du

  3. Instalación y uso de Homebrew Package Manager en Linux

  4. Automatice la respuesta usando Expect y Autoexpect en Linux

  5. Cómo verificar el sistema operativo y la versión usando un comando de Linux

Cree unidades virtuales de CD y DVD usando CDEmu en Linux

Acceda al contenido del portapapeles usando Xclip y Xsel en Linux

Cómo hacer una copia de seguridad de archivos y directorios usando Rsync en Linux

Cómo ejecutar aplicaciones de Linux en Windows 10 y 11 usando WSL

Cómo clonar y restaurar una partición de Linux usando el comando dd

Cómo eliminar archivos y directorios usando la línea de comandos de Linux