Le clavier et le C

Fermé
Pierre - 17 mars 2004 à 16:12
Marden Messages postés 1072 Date d'inscription dimanche 11 février 2001 Statut Membre Dernière intervention 29 janvier 2006 - 27 avril 2004 à 17:28
Salut, j'ai un petit problème auquel j'ai pas trouvé de solution.

J'écris actuellement un programme qui traîte en temps réel des données reçues d'un port série. Ces données sont disponibles en permance et donc mon programme n'a pas de fin prévue (j'utilise une boucle while(1){} et je peux/veux pas faire autrement). Je travaille sous linux et quand je veux arrêter le programme CTLR-C marche très bien.

Mon problème est que je veux maintenant ajouter une dernière instruction qui serait une "instruction de fin de programme". Mon idée, lorsque j'appuie sur Q, la boucle while(1) est brisée et ma dernière instruction est exécutée.

Solution 1: A chaque boucle, lire le clavier. Problème, le programme attend une touche et donc on doit tapper une touche à chaque boucle. Il faudrait un moyen de lui dire de pas attendre ou ne pas utiliser les fonctions de lecture scanf , .. . mais directement lire des registres systèmes (lesquels?)

Solution 2: Utiliser 2 threads (un qui contient la boucle et l'autre qui attend le clavier) mais je sais pas si c'est possible en C et j'ai pas trouvé le moyen de le faire.


Si quelqu'un a une idée ou une solution, je suis prenneur.
Pierre.

5 réponses

tafiscobar Messages postés 1277 Date d'inscription jeudi 7 décembre 2000 Statut Contributeur Dernière intervention 26 février 2009 177
17 mars 2004 à 16:17
3eme solution : les signaux, regarde du cote de posix.

tafiscobar "lou waye def bopame"
la nullite n'existe pas, l'ignorance oui, ah je suppose!!!
0
Salut,
j'ai exactement le meme pb, et en tant que GRAND debutant, je ne comprends pas la reponse de tafiscobar...

Qq'un peu me montrer comment coder ca ?
0
blurk Messages postés 486 Date d'inscription vendredi 16 avril 2004 Statut Membre Dernière intervention 15 mars 2009 160
22 avril 2004 à 12:06
salut,

Il faut trouver une librairie avec une fonction non bloquante
qui détecte si une touche a été frappée (et laquelle)
du genre if(kbhit () ){carac=getasc( );}
avec while (carac!='q') au lieu de while(1)
Je sais que ça existe, ça fait 3 lignes de codes mais malheureusement je ne sais plus où trouver ça
je crois qu'il y a un rapport avec la norme ansi (pour terminal)
mais je suis sûr que sous linux tu devrais pouvoir trouver.

bonne chance, bon courage
0
Justement, c'est bien ca mon pb :
Je ne connais rien a linux, donc je ne sais pas trop ou ni comment chercher...

Mais merci qd mm
0
Marden Messages postés 1072 Date d'inscription dimanche 11 février 2001 Statut Membre Dernière intervention 29 janvier 2006 210
27 avril 2004 à 12:30
La solution passe bien par l'emploi de la fonction"signal" (voir "man signal", pour avoir les détails).
Si l'on tape <Ctrl>+C, le signal est récupéré, et par défaut, le traitement est immédiatement abandonné, avec émision d'un "core". Il faut donc, avant la boucle, remplacer le traitement par défaut (voir SIG_DFL) par une fonction utilisateur positionnant un "flag" accessible du programme appelant (global). C'est ce "flag" que l'on teste dans la boucle pour effectuer une sortie propre de l'application.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Merci, ca a l'air d'etre effectivement la seule solution possible...

Le pb, c'est que je ne vois pas bien comment ca fonctionne concretement :( Je comprend bien le principe, mais l'aide n'est pas tres... limpide
Tu aurais un exemple ?
0
Marden Messages postés 1072 Date d'inscription dimanche 11 février 2001 Statut Membre Dernière intervention 29 janvier 2006 210
27 avril 2004 à 17:28
Désolé, je n'ai pas le détail de la mise en oeuvre dans mes archives. Je garantis que çà marche pour l'avoir utilisé ... il y a une dizaine d'années (j'ai, depuis, rendu mon tablier) dans au moins 2 cas :
* interruption d'édition de listes (des centaines de lignes défilant à l'écran) dans une appli en "conversationnel", et retour au mode "commande".
* interruption du calcul d'une réduction de matrice (méthode de Gauss) dont le calcul pouvait durer plusieurs heures. Le test était effectué à un niveau "logique" du traitement (fin de calcul d'une ligne/colonne), avec sauvegarde de la partie non calculée pour une reprise ultérieure.

Bien lire au préalable ce qui est dit sur "signal()" dans les manuels, je crois que çà y est bien expliqué. En quelques lignes de code.
0