Question

Double Possible:
Ce qui est équivalent à getch() & getche() sous Linux?

Je suis un newbie en linux programmation.:-)

Je me demande juste si mon programme (à l'aide de C de la langue) peut capturer chaque seule touche immédiatement sous linux, et ensuite décider de l'écho ou pas et comment faire pour l'afficher, tout comme telnet.

par exemple, si un utilisateur des grèves "A", je veux que le programme pour l'affichage de 'B', si il tape 'B', 'C' est voulu, et ainsi de suite.

C'est drôle et inutile.Je suis juste curieux.

Était-ce utile?

La solution

Fondamentalement, cela dépend fortement de la façon dont vous définissez immédiatement.

Il y a deux tâches ici. La première consiste à désactiver l'écho de clé régulière intégrée à la plupart des bibliothèques d'entrée C. La seconde est d'imprimer le nouveau personnage au lieu de l'ancien.

en pseudo code.

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

Il existe un certain nombre de systèmes communiquant pour capturer une touche presse.

  1. le clavier
  2. (éventuellement) un bus USB
  3. le gestionnaire d'interruption de la CPU
  4. le système d'exploitation
  5. Le processus X Window Server
  6. la x "fenêtre" qui a la focalisation.
  7. La dernière étape est effectuée avec un programme qui exécute une boucle continue qui capture les événements du serveur X et les traite. Si vous souhaitiez élargir ce programme de certaines manières (obtenez la limite de la clé de la touche), vous devez dire aux autres programmes que vous souhaitez des événements de clavier "bruts", ce qui signifie que vous ne recevrez pas vraiment complètement "cuit " personnages. En conséquence, vous devrez garder une trace de laquelle les clés sont de haut en bas, et combien de temps et gèrent tout le comportement impair méta clé dans votre programme (ce n'est pas un «A», c'est un «A» car Shift est en panne, etc.).

    Il existe également d'autres modes de traitement à prendre en compte, tels que canoniques et non canoniques, qui contrôleront si vous souhaitez que les événements soient reçus dans des morceaux orientés vers la ligne (événements de ligne) ou des morceaux orientés du caractère (événements de caractère). Encore une fois, cela est quelque peu compliqué selon la nécessité de sensibiliser les programmes en amont des exigences du client en aval.

    Maintenant que vous avez une idée de votre environnement, revisitons le code actuel nécessaire pour supprimer la sortie du caractère.

    // 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);
    

    Même ce n'est pas immédiat. Pour obtenir immédiatement, vous devez vous rapprocher de la source, ce qui signifie finalement un module de noyau (qui n'est toujours pas aussi immédiat que le micro-contrôleur du clavier, qui n'est pas aussi immédiat que le moment où le commutateur se ferme réellement). Avec suffisamment d'articles entre la source et la destination, il devient finalement possible de remarquer la différence, cependant, dans la pratique, ce code a été travaillé sur beaucoup de personnes qui recherchent le meilleur compromis entre la performance et la flexibilité.

Autres conseils

Edwin Buck a fourni une excellente réponse.Voici une autre alternative qui utilise ncurses qui fait de telles choses un peu plus faciles et est prise en charge sur presque toutes les distributions Linux et d'autres variantes 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);
}

Compilez avec GCC Code.c -O Code -Lncurses

Et voici quelques liens de soutien:

NCurses NOECHO ET AUTRE-MAN Page
Programmation NCurses HOWTO

Ce code peut être trouvé dans l'internet et c'est par kermi3 à partir de c-conseil

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

EDIT: bien sûr que si vous voulez obtenir le char lui-même et non pas la valeur ascii de changement de char au lieu de int

Il peut être surchargé, mais vous pouvez utiliser des bibliothèques de jeux tels que sdl pour atteindre cela.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top