probleme avec fgets - C - Programmation
Marsh Posté le 27-12-2006 à 19:09:50
Moi je me ferai jamais au C, vous declarez des variable 'Int' et vous leur affectez des 'char', c'est exceptionnel tout de même.
Marsh Posté le 27-12-2006 à 20:39:54
vi bon je me suis trompé
je remets :
Code :
|
Le problème reste le même...
Marsh Posté le 27-12-2006 à 22:20:07
Ben donne le code qui va pas, on y verra plus clair, car là on ne voit point de fgets
Marsh Posté le 27-12-2006 à 22:32:19
ReplyMarsh Posté le 27-12-2006 à 22:34:32
HomerJK a écrit : Bonjour
|
Si tu es l'auteur du "scanf" parasite, remplace-le par un "fgets" et tu n'auras plus aucun problème. D'ailleurs, ce "scanf" n'est pas n'importe quel scanf car le seul moment ou "scanf" laisse un "\n", c'est quand tu l'utilises pour faire saisir un nombre (à ce moment là, "scanf" s'arrête au premier caractère qui n'est pas "nombre" ). Donc t'as plusieurs solutions
1) tu remplaces TOUS les scanf par des "fgets". Et si tu dois faire saisir un nombre, tu fais d'abord un "fgets" dans une zone tampon puis ensuite un "sscanf" de la zone tampon vers ton nombre
ou alors
2) chaque fois que tu fais saisir un nombre par "scanf", tu fais ensuite un "getchar()" pour supprimer le "\n" résiduel
Personnellement, je préfère la "1".
Eh non. Ce qui est exceptionnel, c'est que tu ne cherches pas à comprendre le pourquoi du comment du C et que tu te contentes de critiquer sans réaliser que ceux qui ont écrit les choses avaient quand-même réfléchi bien avant toi...
En C, le char et le int sont quasiment pareil... ce ne sont que des nombres. Le char est un nombre codé sur 8 bit, le int est un nombre codé sur 16 bits. Donc leur seule différence sera la plage de valeurs qu'on peut coder. Avec un char on peut coder 256 valeurs de -128 à 127 en signé ou de 0 à 255 en non-signé; avec un int on peut coder 65536 valeurs de -32768 à 32767 en signé ou de 0 à 65535 en non-signé. Maintenant qu'on utilise un char ou un int pour coder le nombre "64" importe peu puisque les deux conviennent.
Maintenant la fonction "getchar". Son but est de renvoyer un caractère saisi au clavier, donc un caractère codé dans la plage des codes ascii (entre 0 et 255). Mais il faut que "getchar()" puisse renvoyer une valeur supplémentaire signifiant "j'ai rien lu" ou bien "le tampon stdin est vide". Donc getchar doit pouvoir coder au total une valeur supplémentaire ne faisant pas partie de la plage "[0-255]". Mais comme le char s'arrête justement à cette plage "[0-255], la fonction "getchar" ne peut pas être de type "char". C'est pourquoi, bien que dans 99,99% des cas la valeur renvoyée par "getchar" soit un char, cette fonction est de type "int". Et chaque fois qu'elle renverra un caractère saisi elle renverra une valeur de type "0x00nn" ("nn" étant le code ascii du caractère saisi)... jusqu'au moment où elle devra renvoyer "il n'y a plus rien" elle là, renverra la valeur "0xffff"
Marsh Posté le 27-12-2006 à 23:16:35
Sve@r a écrit : |
Peut-être était-ce la norme au temps de Kernighan & Ritchie, mais il me semble que maintenant c'est 32 bits pour les int et 64 pour les long.
Marsh Posté le 27-12-2006 à 23:33:39
apprentitux a écrit : Peut-être était-ce la norme au temps de Kernighan & Ritchie, mais il me semble que maintenant c'est 32 bits pour les int et 64 pour les long. |
Pour un int, la plage garantie par la norme est -32767 à + 32767. Evidemment, selon l'implémentation, ça peut être plus, mais pas moins.
Marsh Posté le 27-12-2006 à 23:35:20
HomerJK a écrit : Y-a-t-il un moyen de remédier à cela ? |
Oui, utiliser fgets() exclusivement et correctement.
http://mapage.noos.fr/emdel/notes.htm#saisie
http://mapage.noos.fr/emdel/notes.htm#fichier
Marsh Posté le 27-12-2006 à 23:36:49
Pas de Int en C. C'est int. C'est le type retourné par fgetc() et celui de EOF. C'est donc tout à fait adapté.
Tu voulais prouver que tu ne connaissais rien au C ? C'est réussi.
Marsh Posté le 28-12-2006 à 00:34:23
Merci pour vos réponses !
Sve@r, personnellement je préfère la solution 2, parce que j'ai mis énormément de scanf pour les entiers, ca va être plus facile d'y remédier.
J'essaye ca et je vous en parle demain.
Marsh Posté le 28-12-2006 à 00:45:09
HomerJK a écrit : personnellement je préfère la solution 2, parce que j'ai mis énormément de scanf pour les entiers, |
Grave erreur... scanf() n'est une fonction difficile à utiliser correctement...
http://xrenault.developpez.com/tutoriels/c/scanf/
Je recommande d'écrire une bonne fois pour toutes, une fonction de saisie pour les entiers, basée sur une fonction de saisie pour les lignes, basée sur fgets() ou fgetc().
http://mapage.noos.fr/emdel/inputs.htm
http://mapage.noos.fr/emdel/clib.htm
Module IO
Marsh Posté le 28-12-2006 à 02:25:58
Emmanuel Delahaye a écrit : Pas de Int en C. C'est int. C'est le type retourné par fgetc() et celui de EOF. C'est donc tout à fait adapté. |
Voulez-vous le prototype de fgets ? Ca m'etonne de votre par Emmanuel
Marsh Posté le 28-12-2006 à 02:39:08
Quel rapport ? Tu as fait une remarque sur un code contenant getchar(), c'est à dire fgetc(stdin). Donc je parle de fgetc(). Quel rapport avec fgets() ?
Rappel des faits :
Code :
|
ce que tu as commenté ainsi :
<<Moi je me ferai jamais au C, vous declarez des variable 'Int' et vous leur affectez des 'char', c'est exceptionnel tout de même.>>
Ce qui a fait réagir mon troll-o-meter, soit dit en passant...
Marsh Posté le 28-12-2006 à 02:45:52
Bref, je me suis embrouillé entre lee prototype des fonction utilisé dans le code donné et les prototype des fonction utilisé dans le code à debuger. C'est vrai que c'est un langage surprenant
Mes excuses HomerJK, je t'ai un induit(e) en erreur, mea culpa.
Marsh Posté le 28-12-2006 à 11:10:45
HomerJK a écrit : Sve@r, personnellement je préfère la solution 2, parce que j'ai mis énormément de scanf pour les entiers, ca va être plus facile d'y remédier. |
T'es totalement libre de tes préférences. Mais le problème de "scanf" c'est que ça attend une entrée "formatée". Et, par définition, ce que tape le gogelu à qui on lui dit "entrez un chiffre" est tout sauf formaté et souvent tout sauf du chiffre. Donc la solution optimale est de tout accepter "en vrac" et de faire le tri ensuite. Ca permet au-moins d'avoir un tampon stdin toujours clean. Et c'est pas tellement difficile de transformer du scanf en fgets; même s'il y en a beaucoup
Exemple
int nb; |
Solution 1
int nb; |
Solution 2
int nb; |
Moi je ne choisirais pas une solution plutôt que l'autre par facilité d'écriture... mais plutôt par l'accroissement de sécurité qu'elle donne...
Marsh Posté le 28-12-2006 à 11:55:06
ReplyMarsh Posté le 28-12-2006 à 16:36:37
nyrk a écrit : Ce qui est surprenant pour l'instant c'est ta stupidité. |
Ben quand-même !!!
Il a reconnu son erreur et il s'est excusé. Moi je n'ai vu aucune stupidité dans ses propos... seulement de l'ignorance. Et, de mon point de vue, ce n'est absolument pas une tare. Mais peut-être que tu sais tout sur tout et que tu n'es donc pas de mon avis...
Voici quand-même la définition de "stupide" vue par Bernard Werber (tu devrais connaître si tu lis autre-chose que oui-oui au pays des jouets) :
Citation : Stupide du latin "stupidus", signifie étonné, frappé de stupeur. Le stupide est celui qui s'étonne de tout. Il a conservé sa capacité d'émerveillement face à la nouveauté. Il est le contraire du blasé. |
Marsh Posté le 28-12-2006 à 17:13:45
C'est bon j'ai réglé mon problème !
J'ai donc mis getchar() après chaque scanf() (la solution la plus simple car j'ai énormément de scanf dans mon programme).
Mais la prochaine fois j'utiliserais une autre de vos méthodes, promis !
Merci beaucoup !
Marsh Posté le 28-12-2006 à 17:32:51
HomerJK a écrit : C'est bon j'ai réglé mon problème ! |
YES !!! J'étais en effet terriblement inquiet quand à la réussite de ton prog...
HomerJK a écrit : Mais la prochaine fois j'utiliserai |
Aujourd'hui encore, Emmanuel et moi pourrons nous coucher le coeur en paix en sachant que nous avons sauvé une âme de plus de la perdition. Devoir accompli...
Marsh Posté le 28-12-2006 à 18:18:16
HomerJK a écrit : C'est bon j'ai réglé mon problème ! |
y'a que moi qui trouve cette solution hyper crade ? ca tient plus du bricolage que d'autre chose...
Marsh Posté le 28-12-2006 à 18:22:02
Tamahome a écrit : y'a que moi qui trouve cette solution hyper crade ? ca tient plus du bricolage que d'autre chose... |
On a proposé autre chose, mais il se croit plus malin que nous, alors laisse tomber...
Marsh Posté le 28-12-2006 à 18:29:02
Tamahome a écrit : y'a que moi qui trouve cette solution hyper crade ? ca tient plus du bricolage que d'autre chose... |
Ce n'est pas vraiment "hyper" crade. Il a un "\n" parasite donc il l'enlève et c'est bon. C'est juste que ce getchar ne marche que s'il n'y a qu'un seul "\n" parasite. S'il y a autre chose (parce que l'utilisateur débile a tapé "azertuiop" là où on lui demandait un nombre) ça ne marche plus alors que l'autre solution à base de "fgets" marche encore. Je préfère aussi le "fgets()" et d'autres probablement aussi... mais chacun est (encore) libre de programmer comme il le sent.
Marsh Posté le 28-12-2006 à 18:36:32
Sve@r a écrit : chacun est (encore) libre de programmer comme il le sent. |
C'est pas de la liberté, c'est ne pas vouloir prendre suffisament de recul pour reconnaître que son code doit être revu.
J'ai un collègue qui code au copier-coller et qui crée des fonctions de 5000 lignes. Je lui ai dit de créer une fonction plutôt que de recopier un bout de code qu'il réutilise plusieurs fois (j'ai beaucoup réduit mes attentes sur sa qualité de code), mais c'est toujours si je ne passe pas pour un chieur.
Et au final, que ce soit un mois plus tard pour ajouter une fonctionnalité, ou trois ans après lorsque le code est repris, on se retrouve avec un taux de suicide anormalement haut pour la profession.
Donc si l'on envisage le taux considérable de dépressions nerveuses, j'estime que l'on a une responsabilité envers ses collègues et toute personne qui, un jour ou l'autre, lira notre code. Et comme je suis un bon citoyen et que j'aspire à réduire les dépenses de la sécurité sociale, je trouve inadmissible que l'on se permette encore de coder avec les pieds comme tout roumain schyzophrène dyslexique en camisole.
Marsh Posté le 28-12-2006 à 18:47:00
Elmoricq a écrit : C'est pas de la liberté, c'est ne pas vouloir prendre suffisament de recul pour reconnaître que son code doit être revu. |
Totalement d'accord. J'aurais du être plus explicite et dire "chacun est encore libre de programmer comme il le sent à condition qu'il programme pour lui tout seul pour se faire plaisir ou bien pour faire un truc dont la durée de vie n'excède pas la demi-semaine".
Dans le cas où évidemment il oeuvre en communauté, sa liberté de programmeur s'arrête là où commence celle de celui qui va le relire...
Elmoricq a écrit : J'ai un collègue qui code au copier-coller et qui crée des fonctions de 5000 lignes. Je lui ai dit de créer une fonction plutôt que de recopier un bout de code qu'il réutilise plusieurs fois (j'ai beaucoup réduit mes attentes sur sa qualité de code), mais c'est toujours si je ne passe pas pour un chieur. |
J'ai connu ça aussi. Le type qui se gargarisait en disant "je code des millions de lignes de C par jour". Bon... ça passe et ça s'oublie...
Marsh Posté le 28-12-2006 à 19:07:15
Sve@r a écrit : J'ai connu ça aussi. Le type qui se gargarisait en disant "je code des millions de lignes de C par jour". Bon... ça passe et ça s'oublie... |
J'ai lu quelque part (je crois que c'est dans 'Tout sur le code' de Steve McConnell) qu'un programmeur sérieux écrivait 10 à 25 lignes de code testé par jour en moyenne...
Marsh Posté le 28-12-2006 à 19:10:15
Emmanuel Delahaye a écrit : J'ai lu quelque part (je crois que c'est dans 'Tout sur le code' de Steve McConnell) qu'un programmeur sérieux écrivait 10 à 25 lignes de code testé par jour en moyenne... |
Il n'y a aucune incohérence entre ton chiffre et le mien. Ce type ne m'as jamais dit qu'il était sérieux... ni que ses millions de lignes étaient testées. Il m'a juste dit qu'il les écrivait...
Marsh Posté le 28-12-2006 à 19:37:10
Sve@r a écrit : Ben quand-même !!!
|
C'est marrant, cette définition me semble coller à ce que disait jovalise.
Pour ce qui est de Bernard Werber, c'est de la sous S.-F. qui convient bien aux jeunes gens qui veulent passer au stade immédiatement supérieur à "Oui-oui".
Marsh Posté le 28-12-2006 à 20:28:37
Sve@r a écrit : Ce n'est pas vraiment "hyper" crade. Il a un "\n" parasite donc il l'enlève et c'est bon. |
La tu soignes les symptomes, pas la maladie...
Marsh Posté le 28-12-2006 à 20:46:56
Tamahome a écrit : La tu soignes les symptomes, pas la maladie... |
Ben parfois, si t'as mal à la tête tu prends une aspirine sans chercher plus loin. Si ton mal de tête est récurrent, là tu peux commencer à voir plus loin.
Pour son pb, Emmanuel et moi lui avons expliqué la cause du problème et les différentes façons de le résoudre, avec les avantages et inconvénients de chacune des façons. Apparemment HomerJK a bien compris. Maintenant si "soigner le symptôme" lui convient et que son programme qu'il écrit pour se faire plaisir pour lui tout seul fonctionne comme ça, pourquoi aller plus loin ?
PS: T'es plus "lt-commander Data" ??? Je ne connais pas "Pilote Gundam" bien que je connaisse un bouquin de P-J Hérault nommé "Pilote Gurvan"...
Marsh Posté le 28-12-2006 à 21:46:32
Sve@r a écrit : PS: T'es plus "lt-commander Data" ??? Je ne connais pas "Pilote Gundam" bien que je connaisse un bouquin de P-J Hérault nommé "Pilote Gurvan"... |
aucun rapport
http://www.gundam.jp/
Marsh Posté le 27-12-2006 à 18:59:03
Bonjour
j'ai un ptit probleme avec le fontion fgets()
En effet, quand j'utilise cette methode pour faire rentrer une chaine de caracteres dans une variable, je saute lors de l'excution du programme l'instruction qui appelle fgets();
Mais après avoir lu certains posts, je sais maintenant que cela provient de l'utilisation antérieure d'un scanf() qui laisse trainer un '\n' que récupère fgets();
Du coup je vide le buffer clavier avec cette instruction :
Ca marche, seulement voilà, lorsque je veux afficher et enregistrer dans un fichier la chaine de caractères entrée par fgets(), elle fait sauter une ligne dans l'affichage et de même dans le fichier.
Y-a-t-il un moyen de remédier à cela ?