GNU/Linux >> Tutoriels Linux >  >> Linux

Utiliser kbhit() et getch() sous Linux

Si votre Linux n'a pas de conio.h qui prend en charge kbhit() vous pouvez chercher ici le code de Morgan Mattews pour fournir kbhit() fonctionnalité d'une manière compatible avec n'importe quel système compatible POSIX.

Comme l'astuce désactive la mise en mémoire tampon au niveau des termios, elle devrait également résoudre le problème getchar() problème comme démontré ici.


Le guide ncurses cité ci-dessus peut être utile. Voici un exemple illustrant comment ncurses pourrait être utilisé comme l'exemple 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");
    }
}

Notez qu'avec ncurses, le iostream l'en-tête n'est pas utilisé. En effet, mélanger stdio avec ncurses peut avoir des résultats inattendus.

ncurses, soit dit en passant, définit TRUE et FALSE . Un ncurses correctement configuré utilisera le même type de données pour bool de ncurses comme compilateur C++ utilisé pour configurer ncurses.


Une solution compacte basée sur la réponse de Christophe est

#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;
}

Contrairement à cette réponse, cela ne laissera pas le terminal dans un état étrange après la fermeture du programme. Cependant, il laisse toujours les caractères assis dans le tampon d'entrée, de sorte que la touche qui a été enfoncée apparaîtra de manière indésirable sur la prochaine ligne d'invite.

Une solution différente qui résout ce problème est

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;
}

L'utilisation est la suivante

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

Désormais, tous les caractères saisis entre l'exécution de la première et de la dernière ligne n'apparaîtront pas dans le terminal. Cependant, si vous quittez avec Ctrl+C le terminal est laissé dans un état bizarre. (Soupir)


Linux
  1. Déboguer Linux avec ProcDump

  2. Vérifier l'espace disque sous Linux à l'aide des commandes df et du

  3. Utilisation de ssh-keygen et partage pour l'authentification par clé sous Linux

  4. Automatiser la réponse à l'aide de Expect et Autoexpect sous Linux

  5. Comment vérifier le système d'exploitation et la version à l'aide d'une commande Linux

Créer des lecteurs de CD et de DVD virtuels à l'aide de CDEmu sous Linux

Accéder au contenu du presse-papiers à l'aide de Xclip et Xsel sous Linux

Comment sauvegarder des fichiers et des répertoires à l'aide de Rsync sous Linux

Comment exécuter des applications Linux sur Windows 10 et 11 à l'aide de WSL

Comment cloner et restaurer une partition Linux à l'aide de la commande dd

Comment supprimer des fichiers et des répertoires à l'aide de la ligne de commande Linux