begin process at 2010 09 06 12:30:11
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Applications Linux

 > FONCTIONS KBHIT() ET GETCH() SOUS LINUX (DOIT MARCHER AVEC TOUT OS À BASE D'UNIX, FREEBSD, ETC .....)

FONCTIONS KBHIT() ET GETCH() SOUS LINUX (DOIT MARCHER AVEC TOUT OS À BASE D'UNIX, FREEBSD, ETC .....)


 Information sur la source

Note :
6 / 10 - par 1 personne
6,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Applications Linux Niveau :Débutant Date de création :31/03/2003 Date de mise à jour :31/03/2003 21:16:58 Vu :22 247

Auteur : bouba

Ecrire un message privé
Site perso
Commentaire sur cette source (19)
Ajouter un commentaire et/ou une note

 Description

Je suis sûr que beaucoup se sont pris la tête à chercher l'équivalent des fonctions getch() et kbhit() de windows sous Linux. Ne cherchez plus!!! Elles n'existent pas malheuresement. J'ai donc créé une classe pour afin de pouvoir utiliser des fonctions similaires sous Linux. Je pense que ca va aider beaucoup de monde !!!!!

Source

  • /******************/
  • /* Keybord.h */
  • /*****************/
  • #include <termios.h>
  • #include <unistd.h>
  • #include <stdlib.h>
  • class Keyboard
  • {
  • private:
  • struct termios initial_settings, new_settings;
  • public:
  • void Initialisation();
  • void Arret();
  • int kbhit();
  • int getch();
  • };
  • /********************/
  • /* Keyboard.cpp */
  • /*******************/
  • #include "Keyboard.h"
  • int Keyboard::getch()
  • {
  • char ch;
  • read(0,&ch,1);
  • return ch;
  • }
  • int Keyboard::kbhit()
  • {
  • char ch;
  • new_settings.c_cc[VMIN]=0;
  • tcsetattr(0,TCSANOW, &new_settings);
  • read(0,&ch,1);
  • new_settings.c_cc[VMIN]=1;
  • tcsetattr(0,TCSANOW, &new_settings);
  • return ch;
  • }
  • void Keyboard::Initialisation()
  • {
  • tcgetattr(0,&initial_settings);
  • new_settings = initial_settings;
  • new_settings.c_lflag &= ~ICANON;
  • new_settings.c_lflag &= ~ECHO;
  • new_settings.c_lflag &= ~ISIG;
  • new_settings.c_oflag &= ~NL0;
  • new_settings.c_oflag &= ~CR0;
  • new_settings.c_oflag &= ~TAB0;
  • new_settings.c_oflag &=~BS0;
  • new_settings.c_cc[VMIN] = 1;
  • new_settings.c_cc[VTIME] = 0;
  • cfsetospeed (&new_settings, B230400);
  • cfsetispeed(&new_settings, 0);
  • tcsetattr(0, TCSANOW, &new_settings);
  • }
  • void Keyboard::Arret()
  • {
  • tcsetattr(0, TCSANOW, &initial_settings);
  • }
/******************/
/*  Keybord.h   */
/*****************/

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

class Keyboard
{
	private:
		struct termios initial_settings, new_settings;
	public:
		void Initialisation();
		void Arret();
		int kbhit();
		int getch();
}; 


/********************/
/* Keyboard.cpp */
/*******************/

#include "Keyboard.h"


int Keyboard::getch()
{
	char ch;
	read(0,&ch,1);
	return ch;
}


int Keyboard::kbhit()
{
	char ch;
	new_settings.c_cc[VMIN]=0;
	tcsetattr(0,TCSANOW, &new_settings);
	read(0,&ch,1);
	new_settings.c_cc[VMIN]=1;
	tcsetattr(0,TCSANOW, &new_settings);
	return ch;
}

void Keyboard::Initialisation()
{
	tcgetattr(0,&initial_settings);
	new_settings = initial_settings;
	new_settings.c_lflag &= ~ICANON;
	new_settings.c_lflag &= ~ECHO;
	new_settings.c_lflag &= ~ISIG;
	new_settings.c_oflag &= ~NL0;
	new_settings.c_oflag &= ~CR0;
	new_settings.c_oflag &= ~TAB0;
	new_settings.c_oflag &=~BS0;
	new_settings.c_cc[VMIN] = 1;
	new_settings.c_cc[VTIME] = 0;
	cfsetospeed (&new_settings, B230400);
	cfsetispeed(&new_settings, 0);
	tcsetattr(0, TCSANOW, &new_settings);
}

void Keyboard::Arret()
{
	tcsetattr(0, TCSANOW, &initial_settings);
} 

 Conclusion

Bon, j'explique un peut comment utiliser la classe.
Dabord il faut instancier celle-ci:
Par exemple:
Keyboard Clavier;
Ensuite on peut utiliser les fonctions comme ceci.
Clavier.kbhit(); //Equivalent de kbhit() sous Windows
Clavier.getch(); //Equivalent de getch() sous Windows
Après avoir utilisé ces fonction il faut faire ceci
Clavier.Arret();

Attention!!!!!! Avant toute sortie sur l'écran de la console il faut appeler la fonction Arret() afin de remettre l'echo sans quoi rien ne va s'afficher. Puis ensuite rappeler la fonction Initialisation() si l'on souhaite utiliser de nouveau kbhit() et getch().

Pour ceux qui souhaitent savoir comment ca marche.
En fait sous linux il est possible de régler différents paramètres de la konsole en appelant des fonctions bas niveau (c'est donc du C). On peut régler l'echo, la vitesse d'affichage, l'activation du bipper etc .....
C'est comme ceci que j'ai créer kbhit() et getch() et c'est pour cette raison qu'il faut impérativement appeler Arret() avnt toute sortie à l'écran de la konsole afon de restituer les paramètres innitiaux de celle-ci.
Voila, il y a tellemen t à dire que ce ne serait possible de tout mettre ici. Si vous voulez plus d'informations la dessus tapez ceci sous la console: man terminfo

Maintenant bonne prog a tous sous Linux. Le meilleur des OS !!!!
Bouba


 Sources du même auteur

Source avec Zip Source avec une capture EDITEUR DE FICHIERS C++ (LINUX, WINDOWS, MAC...)
CRÉER UNE FENÊTRE AVEC LA XLIB (TOUT OS À BASE D'UNIX (LINUX...
Source avec Zip Source avec une capture EDITEUR DE TEXTE (COMME LE NOTEPAD!!!) [COMPILATEUR BCC55](M...
Source avec une capture EXEMPLE D'UN CUBE PLEIN QUI TOURNE EN OPENGL (UTILISE GLUT)
Source avec Zip Source avec une capture DE LA MISE EN PAGE DANS VOS LABELS QT! C'EST BEAU, ET C'EST ...

 Sources de la même categorie

Source avec Zip Source avec une capture ANIMATIION GRAPHIQUE DES STRUCTURES DE DONNÉES par algoro
PILOTAGE DES 8 SORTIES DU PORT // par cedpic
Source avec Zip PARALLEL OBJECT PROGRAMMING IN C++ (POP-C++) : DEMO par lwinkler
Source avec Zip VOTE ELECTRONIQUE par luvianne
REMOTE POST PHP WITH SOCKET LINUX par 0x0syscall

Commentaires et avis

Commentaire de yapud le 02/04/2003 12:52:21

Bonjour,

Juste pour dire : La fonction GETCH() existe déjà sous LINUX. En tout cas dans ma distribution. Elle se trouve dans CURSES.H et marche comme sous Windows (aprés quelques initialisations).

Voilà c'est tout.

YAPUD

Commentaire de mickbad le 02/04/2003 15:58:54

Salut,

Effectivement la librairie curses est là entre autre pour bénéficier de conio.h sous gnu.

Cependant, si on veut faire du développement en environnement  réduit ou tout simplement faire un programme très petit, il est interessant d'avoir ce genre de code car on n'a pas forcément besoin de toutes les fonctions.

pour info, la librairie utilisée pour curses fait environ 253Ko ... pas bcp mais des fois c'est largement trop surtout pour utiliser un kbhit() et un getch(), héhé :)))

voilà mais c'est normal de parler de curses (ouf :))
MickBad

Commentaire de bouba le 02/04/2003 19:05:43

Oui, getch() est en effet présent dans curses, je le sais. Mais cette librairie possède son propre mode d'affichage, il faut utiliser obligatoirement le printw() et pas cout par exemple sans koi ca risque de ne pas produire l'effet souhaité, curses est une librairie utilisée pour programmer en C et pas en C++. Et puis de tout de façon kbhit() n'est pas sous curses. Voila, la classe que j'ai créée est donc parfaite pour être utilisé dans un programme basic C ou C++ avec affichage sous konsole normal (pas d'affichage spécifique a une librairie comme curses ou autre). Si vous le souhaitez vous pouvez modifier mon code afin de ne pas avoir de classe mais une simple fonction. Mais je trouve ke c'est plus claire comme ceci.
Bouba

Commentaire de mickbad le 02/04/2003 22:11:42

Emulation en C de la fonction kbhit que j'utilise souvent dans mes dev sur linux

... et c'est la même chose que toi sans class :))

ta classe est très bien (sisi) mais avantage de la fonction type C: facile de faire le dev cross-plateforme ensuite (ie : dans le main par exple, lorsque tu appelles kbhit(), tu n'es pas obligé de l'entourer avec des #ifdef _Windows pour gérer la compilation Win32 et GNU :)



#include &lt;termios.h&gt;

int kbhit() {
// * Emulatiion de la fonction kbhit() de DOS
// variables de lecture
char ch;
int nread;
struct termios origTerm, newTerm;

// vérification d'usage
if(peek != -1)
return 1;

// préparation du terminal
tcgetattr(0, &origTerm);
newTerm = origTerm;
newTerm.c_lflag &= ~ICANON;
newTerm.c_lflag &= ~ECHO;
newTerm.c_lflag &= ~ISIG;
newTerm.c_cc[VMIN] = 1;
newTerm.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &newTerm);

// écoute clavier
newTerm.c_cc[VMIN]=0;
tcsetattr(0, TCSANOW, &newTerm);
nread = read(0,&ch,1);
newTerm.c_cc[VMIN]=1;
tcsetattr(0, TCSANOW, &newTerm);

// Rétablissement du terminal
tcsetattr(0,TCSANOW, &origTerm);

// test de lecture
if (nread == 1) {
peek = ch;
return 1;
}
return 0;
} // fin de la fonction kbhit()


ceci dit ... la classe C++ est fort intéressante car applicable facilement !

MickBad

Commentaire de bouba le 03/04/2003 07:40:21

Tu as un pe raison c'est vrai, c'est plus pratique de mettre ca dans une simple fonction, en tout cas je suis sûr que ca va servir au newbies de la prog sous Linux.
Merci MickBad
Bouba

Commentaire de sylvainmarechal le 15/10/2003 11:26:03

Juste 1 ptite remarque :
Vous pourriez dire que vous avez pompé ce code texto ds le bouquin "Beginning Linux Programming" de www.wrox.com :
http://web.wrox.com/0764543733/2971.tar.gz (kbhit.c)

Sylvain

Commentaire de mickbad le 15/10/2003 12:59:47

pfff ...

OpenSource man : on se sert des travaux de tout le monde pour avancer plus vite, non ?

en tout cas, ce code existe bien avant ce livre je te le garanti et aussi d'en d'autre livre comme "Programmation système en C sous Linux" (bien qu'il faille faire queque transformation :))

enfin pense aussi à ceux qui recherche ce genre de fonction et ne savent pas ou réellement trouver !


Commentaire de sylvainmarechal le 15/10/2003 15:24:33

D'acc sur tous les points avec toi, sauf que qd on pompe du code, c'est toujours utile de donner ses sources (ds ts les sens du terme) , plutot que de dire qu'on l'a fait soit meme ("J'ai donc créé une classe") alors qu'on retrouve le meme code mot pour mot un peu partout sur Internet.
c vrai, j'oubliais, peut etre que l'auteur de cet article est lui meme a l'origine de cet exemple ;-)
Sans rancune,
Sylvain

Commentaire de Siriusgalaxie26 le 04/02/2004 14:31:54

Pas mal la converstion... et qu'en est-il de par exemple la fonction clrscr() ??

Commentaire de sylvainmarechal le 04/02/2004 17:41:31

Essaye ca : (en prime, gotoxy() et _setcursortype())

#define _NOCURSOR 0
#define _SOLIDCURSOR 1
#define _NORMALCURSOR   2

#define gotoxy( x, y) printf("\033[%d;%dH", y, x)
#define  clrscr() printf("\033[2J")
#define _setcursortype( cur_t )

Commentaire de Siriusgalaxie26 le 04/02/2004 19:28:32

Ouais, ca marche, merci :-)

Un seul hic, quand j'efface l'écran avec ta methode, il ne me remet pas en haut à gauche, mais fait un "trou" dans la console. Je pense pourvoir bidouiller avec ton gotoxy() (très utile. merci)

A+

Commentaire de Siriusgalaxie26 le 04/02/2004 19:57:03

#define gotoxy( x, y) printf("\033[%d;%dH", y, x)
void clrscr(void){    
printf("\033[2J");
gotoxy(0,0);
}

Voila le clone de la fonction clsrcr() de conio.h, made by Sylvain et Sirius

Commentaire de BlackGoddess le 12/06/2004 11:31:55

les extern "C" pour les includes / déclarations C :o
sinon, je pense que Initialisation devrait etre le constructeur, et Arret le destructeur, c'est tout l'interet de l'encapsulation dans une classe.
Egalement je pense que ce serait une bonne idée de fournir une interface portable, pour cela mettre des #ifdef WIN32 un peut partout pour selectionner les bons includes, et le bon code a executer.

Commentaire de GlanduSchmoldu le 03/05/2005 19:28:48

Bon alors je comprend pas bien comment ça marche.
Si VMIN = 0, j'ai des problèmes, c'est à dire que kbhit me renvoie le code de la dernière touche pressée, même quand j'arrête d'appuyer, donc je peux pas savoir si on vient d'appuyer ou pas. J'ai essayé en regardant le nombre de caractères lus comme dans la remarque de mickbad, mais ça renvoie tjrs la même valeurs, une centaine de millions.

En fait si qqun pouvois m'expliquer comment marche la fonction read je comprendrais mieux.

Enfin bon c'est qd même déjà bien, merci.

Commentaire de GlanduSchmoldu le 09/05/2005 21:31:07

Bon j'ai compris. Chez moi, la fonction read(), grâce aux manips de bouba (que je remercie), n'attend pas la touche entrée pour se débloquer, mais par contre elle l'attend pour repermettre l'affichage, donc rien ne s'affiche tant qu'on ne fait pas un printf("\n"). Pas très grave mais chez moi ça me posais problème.
Il suffit donc, si par hasard qqun avait ce genre de problème, de remplacer read() par getchar().
Voilà.

Commentaire de MrAhah le 15/12/2007 12:44:04

Merci beaucoup pour ton code :)
Bonne continuation :)

Commentaire de roger400t le 05/02/2009 19:07:35

Merci pour ce code.
Le premier résultat dans google fonctionne du premier coup c'est merveilleux.
Personnellement, j'ai remplacé Initialisation et Arret par un constructeur et un destructeur.
C'est plus paresseux à utiliser.

Commentaire de cyk1986 le 20/08/2009 12:23:49

MERCI !
pour ceux qui voudraient exploiter de manière simple, un exemple bête avec le fflush en plus (chez moi ça ne marche pas bien sans ça.(ubuntu))
char a=100;
Keyboard Clavier;
Clavier.Initialisation();
while (a--)
{
printf ( "\a%c_", Clavier.getch() );
fflush (stdout);
}
Clavier.Arret();

Commentaire de cyk1986 le 20/08/2009 12:24:41

en lisant les comment plus haut, je précise: fflush (stdout); permet de ne aps faire de "\n" pour afficher la sortie.

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Septembre 2010
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
27282930   

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,967 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales