[C] getch getchar getc et gcc 3.3.2 [Resolu]

getch getchar getc et gcc 3.3.2 [Resolu] [C] - C - Programmation

Marsh Posté le 21-12-2004 à 13:29:11    

Salut a tous  :)  
 
Voila, j'ai un petit souci avec un bout de code tout bete :
 

Code :
  1. printf("Appuyez sur une touche puis entree quand vous etes pret ...\n" );
  2. getchar();


 
Le getchar n'attend pas la frappe d'une touche, il passe directement a la suite.
J'ai le meme probleme en utilisant getc(stdin) (qui est l'equivalent).
Je suis sous MDK 10.0, et ce qui m'ennuie, c'est qu'en testant le meme code sous FC2 tout passe nickel ...
 
J'ai essaye d'utiliser getch() avec curses.h, mais la j'ai l'erreur suivante a la compilation :
 

gcc -o client client.c
/home/whiterabbit/tmp/ccetfA7Q.o(.text+0x2a1d): In function `Jeu(int)':
: undefined reference to `stdscr'
/home/whiterabbit/tmp/ccetfA7Q.o(.text+0x2a22): In function `Jeu(int)':
: undefined reference to `wgetch'
collect2: ld returned 1 exit status


 
Vous avez une idee ?
 
Merci d'avance  :D
 
edit : la question est de savoir si cela viendrait de ma version de gcc ou d'autre chose ... et s'il existe une alternative permettant d'avoir le meme effet, sans avoir a recoder la fonction comme Taz l'a deja indique dans un autre post.


Message édité par whiterabbit le 22-12-2004 à 13:51:13
Reply

Marsh Posté le 21-12-2004 à 13:29:11   

Reply

Marsh Posté le 21-12-2004 à 13:31:27    

hein ? getchar / fgetc attende qu'on appuie sur entrée ... sinon, ça veut dire que tu as foiré un scanf/printf avant

Reply

Marsh Posté le 21-12-2004 à 13:36:41    

Oups, me suis plante sur le message avant le getchar(), je corrige ;-)
 
J'ai eu la meme idee, concernant un eventuel scanf/printf foire en amont, bah j'ai recopie ce bout de code tout simple pour tester, et bien meme avec uniquement ca dans le main, le prog se termine direct, sans attendre de touche ...
 
Je viens de me rendre compte que j'ai egalement le meme probleme avec :

Code :
  1. scanf("%c",&Car);

Reply

Marsh Posté le 21-12-2004 à 13:42:12    

ouais, ben alors ça, c'est la marne, il lit 1 caractère, et après il te reste un '\n' que tu as saisis, mais pas lu. c'est cet '\n' que tu récupères avec ton getchar suivant

Reply

Marsh Posté le 21-12-2004 à 14:04:35    

Bingo, je viens de faire un test sur le caractere recupere, et c'est bien un \n ...
Le truc c'est que je vois pas pourquoi il est encore la ... et comment le virer, vu que le fflush(stdin) n'a pas l'air de fonctionner  :pt1cable:
 
edit : bon bah maniere bourrin, deux getchar() enchaines et c'est bon  :D
par contre, si quelqu'un peut m'indiquer les raisons pour lesquelles je me fais jeter avec un appel a getch(), je suis preneur  :jap:


Message édité par whiterabbit le 21-12-2004 à 14:08:30
Reply

Marsh Posté le 21-12-2004 à 14:58:42    

whiterabbit a écrit :

Salut a tous  :)  
 
J'ai essaye d'utiliser getch() avec curses.h, mais la j'ai l'erreur suivante a la compilation :
 

gcc -o client client.c
/home/whiterabbit/tmp/ccetfA7Q.o(.text+0x2a1d): In function `Jeu(int)':
: undefined reference to `stdscr'
/home/whiterabbit/tmp/ccetfA7Q.o(.text+0x2a22): In function `Jeu(int)':
: undefined reference to `wgetch'
collect2: ld returned 1 exit status


 
Je suis sous MDK 10.0, et ce qui m'ennuie, c'est qu'en testant le meme code sous FC2 tout passe nickel ... vous avez une idee ?
 
Merci d'avance  :D
 
edit : la question est de savoir si cela viendrait de ma version de gcc ou d'autre chose ... et s'il existe une alternative permettant d'avoir le meme effet, sans avoir a recoder la fonction comme Taz l'a deja indique dans un autre post.


 
Je ne vois pas comment ça peut marcher sur FC2 ce code car la ligne de commande de GCC n'est pas la bonne. Il faut lui indiquer qu'il faut se lier à la lib curses avec le flag -lcurses ( ou -lncurses peut-être )

Reply

Marsh Posté le 21-12-2004 à 15:00:29    

whiterabbit a écrit :


Code :
  1. printf("Appuyez sur une touche puis entree quand vous etes pret ...\n" );
  2. getchar();


 
Le getchar n'attend pas la frappe d'une touche, il passe directement a la suite.


C'est parce que précédemment, il doit y avoir un scanf() qui a 'oublié' un '\n' dans stdin.
 
http://mapage.noos.fr/emdel/notes.htm#saisie


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 21-12-2004 à 15:05:03    

Je dirais même plus, il reste certainement un '\n' sur l'entrée standard. Je dirais même plus, il reste certainement un '\n' sur l'entrée standard. Je dirais même plus, il reste certainement un '\n' sur l'entrée standard. Je dirais même plus, il reste certainement un '\n' sur l'entrée standard. Je dirais même plus, il reste certainement un '\n' sur l'entrée standard. Je dirais même plus, il reste certainement un '\n' sur l'entrée standard. Je dirais même plus, il reste certainement un '\n' sur l'entrée standard. Je dirais même plus, il reste certainement un '\n' sur l'entrée standard. Je dirais même plus, il reste certainement un '\n' sur l'entrée standard. Je dirais même plus, il reste certainement un '\n' sur l'entrée standard. Je dirais même plus, il reste certainement un '\n' sur l'entrée standard.


---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
Reply

Marsh Posté le 21-12-2004 à 15:05:57    

whiterabbit a écrit :

Bingo, je viens de faire un test sur le caractere recupere, et c'est bien un \n ...
Le truc c'est que je vois pas pourquoi il est encore la ... et comment le virer, vu que le fflush(stdin) n'a pas l'air de fonctionner


Normal, fflush() ne fonctionne que sur les flux sortants.

Citation :


edit : bon bah maniere bourrin, deux getchar() enchaines et c'est bon  


Ou utiliser d'autres fonctions de saisies... Voir l'article en référence dans mon autre message.

Citation :


par contre, si quelqu'un peut m'indiquer les raisons pour lesquelles je me fais jeter avec un appel a getch(), je suis preneur


getch() n'est pas standard. Ton compilateur peut l'avoir ou non... Peut être manque-t-il une bibliothèque...


Message édité par Emmanuel Delahaye le 21-12-2004 à 15:25:19

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 21-12-2004 à 15:09:10    

Kristoph a écrit :

Je ne vois pas comment ça peut marcher sur FC2 ce code car la ligne de commande de GCC n'est pas la bonne. Il faut lui indiquer qu'il faut se lier à la lib curses avec le flag -lcurses ( ou -lncurses peut-être )


 
Gnie, j'ai mal positionne ma remarque, ce qui fonctionne nickel sous FC2 c'est le code du debut de post ... pour ce qui est du getch je n'ai pas pu le tester sous FC2 (fac) car je suis sous MDK10 (maison)
 
Je corrige tout de suite  :ange:  
 
Merci pour l'info sur le flag, je testerai ca  :jap:
 
edit : fautes d'orthographe corrigees


Message édité par whiterabbit le 21-12-2004 à 23:13:45
Reply

Marsh Posté le 21-12-2004 à 15:09:10   

Reply

Marsh Posté le 21-12-2004 à 15:24:06    

Emmanuel Delahaye a écrit :

Citation :

Normal, fflush() ne fonctionne que sur les flux entrants.


 
Euh .. flux entrant = stdin non ? tu voulais pas dire sortant plutot ?
Pour ce qui est de fflush, j'ai trouve ca sur le forum :
La fonction fflush() a un comportement défini uniquement sur les flux ouverts en écriture tels que stdout. Il est possible que sur votre système, appliquer cette fonction à stdin soit possible, mais c'est alors une extension non standard. Le comportement est indéterminé, et imprévisible."
 
En testant sous FC2, ca passe (donc je suppose que le fflush se comporte bien) et chez moi non ... mais vu que c'est pas prevu pour ca a la base, j'ai rien a dire et je fais avec  :D  
 
 

Citation :

Ou utiliser d'autres fonctions de saisies... Voir l'article en référence dans mon autre message.


 
Si le \n est encore present dans le buffer, dans tous les cas il faut le virer avant de pouvoir utiliser une fonction de saisie ... non ?
 

Citation :

getch() n'est pas standard. Ton compilateur peut l'avoir ou non... Peut être manque-t-il une bibliothèque...


 
Yep, je sais qu'il n'est pas standard, mais bon, c'etait pour essayer.
 


 
 
En tout cas merci a tous pour vos petites infos ;-)

Reply

Marsh Posté le 21-12-2004 à 15:26:03    

whiterabbit a écrit :

Euh .. flux entrant = stdin non ? tu voulais pas dire sortant plutot ?


Si. Corrigé.

Citation :


Si le \n est encore present dans le buffer, dans tous les cas il faut le virer avant de pouvoir utiliser une fonction de saisie ... non ?  


C'est à la fonction de saisie de faire le ménage tout de suite après, sans préjuger de ce qui se passe après (ou avant).


saisie
nettoyage
...
saisie
nettoyage


Les fonctions de saisies basées sur fgets() font la saisie et le nettoyage d'un coup (dans les cas 'normaux').
 
http://mapage.noos.fr/emdel/clib.htm
Module IO
 
 


Message édité par Emmanuel Delahaye le 21-12-2004 à 15:30:37

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 21-12-2004 à 20:45:55    

Oki, c'est note, merci beaucoup  :jap:

Reply

Marsh Posté le 21-12-2004 à 21:42:21    

Bon, le fgets() resoud tous mes problemes (j'aurais jamais pense avoir des ennuis avec les scanf ... lol), par contre il m'en pose un autre ... il arrete la lecture du flux lorsqu'il trouve EOF ou \n ... mais il place quand meme le \n dans la chaine resultat, ce que je ne veux pas ...
gets() serait parfait mais comme il ne gere pas les depassements de buffer, on oublie ...  
 
Pas moyen de trouver pile poil ce qu'il me faut, va falloir que je code une tite routine pour virer \n de ma chaine  :pt1cable:
 
edit : fautes d'orthographe corrigees


Message édité par whiterabbit le 21-12-2004 à 23:12:35
Reply

Marsh Posté le 21-12-2004 à 22:08:29    

c'est normal. alors après un fgets victorieux (~ sans erreur :), tu sors ton strchr, et tu cherche l' '\n' et si tu le trouves, tu fous un bon '\0' dessus et ouala

Reply

Marsh Posté le 21-12-2004 à 23:07:09    

Ouais, mais j'ai fait plus direct, vu que dans ma situation j'ai automatiquement un \n en fin de chaine et que je cherche a le virer systematiquement, je fais ca :

Code :
  1. Chaine[strlen(Chaine)-1]='\0';


 
Voila  :D  
 
Encore merci a vous tous, et bonne soiree  :jap:


Message édité par whiterabbit le 21-12-2004 à 23:10:55
Reply

Marsh Posté le 21-12-2004 à 23:42:58    

whiterabbit a écrit :

Ouais, mais j'ai fait plus direct, vu que dans ma situation j'ai automatiquement un \n en fin de chaine et que je cherche a le virer systematiquement, je fais ca :

Code :
  1. Chaine[strlen(Chaine)-1]='\0';




Marche pas si le '\n' est absent. Il t'a été recommandé d'utiliser strchr(), ce n'est pas sans raisons :

Code :
  1. char *p = strchr (Chaine, '\n')
  2.    if (p != NULL)
  3.    {
  4.       *p = 0;
  5.    }
  6.    else
  7.    {
  8.       /* la ligne n'a pas ete lue entierement.  
  9.        * Il faut agir en consequence (recuperer la suite,  
  10.        * l'ignorer etc.  
  11.        */
  12.    }


Message édité par Emmanuel Delahaye le 21-12-2004 à 23:45:18

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 22-12-2004 à 01:51:30    

Emmanuel Delahaye a écrit :

Marche pas si le '\n' est absent.


 
Oui, mais comme je l'ai precise, dans ma situation (i.e. la maniere dont mon programme fonctionne) je me retrouve systematiquement avec un \n comme dernier caractere, donc ce que j'utilise suffit amplement.
Je ne teste pas le dernier caractere pour savoir si c'est \n et le remplacer si c'est le cas, je le remplace de maniere aveugle.
 
Dans l'hypothese (bug de lecture de la ligne) ou \n ne se trouverait pas en derniere position dans la chaine, comme je remplace le dernier caractere avec \0, bah au pire je tronque la chaine d'un caractere (qui serait deja tronquee suite au bug de lecture) ... et comme cette chaine n'est utilisee que pour un simple affichage ulterieur, c'est pas vraiment un drame  :D (cette chaine n'est pas critique pour le fonctionnement du prog, c'est juste pour une question d'esthetique que je vire \n)
 
Par contre, je suis d'accord avec toi et Taz, dans le cas ou la chaine necessite d'etre traitee de maniere plus rigoureuse, strchr() est necessaire  :jap:  
 
Sur ce, je m'en retourne a mon gcc  ;)  
 
Merci encore  :)


Message édité par whiterabbit le 22-12-2004 à 01:57:41
Reply

Marsh Posté le 22-12-2004 à 07:02:29    

whiterabbit a écrit :

Oui, mais comme je l'ai precise, dans ma situation (i.e. la maniere dont mon programme fonctionne) je me retrouve systematiquement avec un \n comme dernier caractere, donc ce que j'utilise suffit amplement.


Avec fgets(), ce n'est pas garanti. Si tu entres une ligne plus longue que le tampon, la ligne saisie sera tronquée et le '\n' absent.
 
C'est tout l'intérêt de fgets() qui est non seulement sûr (tu connais les problèmes de gets()), mais qui en plus permet de gérer finement la saisie. Si le '\n' est absent, on peut décider d'agrandir le tampon et d'acquérir la suite, ou alors de lire les caractères non lus et de les ignorer. Bref, on a la maîtrise de la saisie...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 22-12-2004 à 13:49:25    

Emmanuel Delahaye a écrit :

Si tu entres une ligne plus longue que le tampon, la ligne saisie sera tronquée et le '\n' absent.


 
Oui, tout a fait d'accord, mais soit je me fais mal comprendre :heink: soit tu n'as pas lu la totalite de mon post  :D  ...  
Si le tampon est trop petit, fgets() tronque la ligne (jusque la on est d'accord), mais comme je remplace systematiquement le dernier caractere de la chaine par \0, dans le pire des cas je me retrouve a tronquer d'un caractere supplementaire une chaine deja tronquee a la saisie ... recuperer une chaine tronquee n'est pas un probleme pour moi, tout ce que je veux c'est virer un \n final, c'est pour ca que ma methode me suffit ;)  
 
Voila, je passe le post en resolu, histoire d'eviter de tourner en rond  :jap:  
 
Bonne journee a tous et bonnes fetes de fin d'annee  :D


Message édité par whiterabbit le 22-12-2004 à 13:49:51
Reply

Marsh Posté le 22-12-2004 à 16:48:42    

whiterabbit a écrit :

Oui, tout a fait d'accord, mais soit je me fais mal comprendre :heink: soit tu n'as pas lu la totalite de mon post  :D  ...  
Si le tampon est trop petit, fgets() tronque la ligne (jusque la on est d'accord), mais comme je remplace systematiquement le dernier caractere de la chaine par \0, dans le pire des cas je me retrouve a tronquer d'un caractere supplementaire une chaine deja tronquee a la saisie ...  


Et tu trouves ça bien ?

Citation :

recuperer une chaine tronquee n'est pas un probleme pour moi, tout ce que je veux c'est virer un \n final, c'est pour ca que ma methode me suffit ;)  


Et tu fais quoi des caractères non lus, et notamment du '\n' qui reste dans le flux entrant ?
 
Tu vas retomber dans le problème du scanf() qui ne lit pas le dernier '\n'...
 
Je te propose une méthode universelle qui marche à tout les coups et toi tu te contentes d'une méthode bancale... C'est ton choix... mais je ne le respecte pas...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 22-12-2004 à 19:28:12    

Emmanuel Delahaye a écrit :


Et tu trouves ça bien ?


 
Dans le cas precis de mon programme oui (dans d'autres situations non) car j'utilise des buffers de 256 caracteres et je suis bien loin de les remplir lors d'une saisie clavier (c'est pour ca que j'indiquais que la probabilite de lecture tronquee etait vraiment faible ... je devrais meme dire nulle)
 

Citation :

Et tu fais quoi des caractères non lus, et notamment du '\n' qui reste dans le flux entrant ?


 
Rien, il n'y en a pas vu que je ne fais jamais de saisie clavier superieure a 256 caracteres
 

Citation :

Je te propose une méthode universelle qui marche à tout les coups et toi tu te contentes d'une méthode bancale... C'est ton choix... mais je ne le respecte pas...


 
Euh, on est pas la pour se taper dessus  :D  
Je ne critique ni ne remets en cause ta methode, je suis d'ailleurs content que tu me l'ai indiquee et je t'en remercie. Mais comme je l'ai deja dit, dans mon cas precis je n'ai pas besoin d'une gestion rigoureuse de la saisie donc ma methode (qui n'est pas bancale dans le contexte de mon programme) me convient tres bien.
 
Oui, dans l'absolu ta methode est vraiment rigoureuse.
J'espere avoir ete assez clair, sinon la prochaine fois je vais etre oblige de poster la totalite de mon code pour me justifier  :lol:  
 
Bonne soiree a tous  ;)


Message édité par whiterabbit le 22-12-2004 à 19:29:37
Reply

Marsh Posté le 22-12-2004 à 19:44:32    

whiterabbit> j'ai pas beaucoup d'expérience mais je pensse que ta démarche n'est pas très bonne, quand on développe on a pas à imaginer que l'utilisateur fera ça ou ça exactement, on doit faire en sorte de prévenir toutes éventualitées, c'est comme mettre des barrières le long d'une route en bordure de falaise. Sur des petites applis perso ça semble peut-être insignifiant mais sur des applis plus complexe ou qui sortent d'un cadre personnel ça devient problématique.  
 
Puis je pensse que ça fait simplement partie des bonnes habitudes à prendre tout simplement, je pensse qu'en info sans rigueur on va droit vers le mur, pas qu'en info d'ailleur...

Reply

Marsh Posté le 22-12-2004 à 19:54:59    

Oui, mais la justement je suis dans l'optique d'une petite appli perso, et plus precisement pour du debug, c'est pour ca que je parle du "contexte" de mon programme. Le seul utilisateur ici sera moi, donc je ne m'avance pas trop en disant que je n'ai pas de risque de me retrouver avec une chaine saisie tronquee.
 
Pour ce qui est de la rigueur qui est de mise en info, on est d'accord sur tout la ligne, et moi aussi je suis pour les barrieres le long des routes qui longent les falaises (et meme le long de toutes les routes dans certains cas).
 
Bye  :hello:  

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed