Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2391 connectés 

  FORUM HardWare.fr
  Programmation
  C

  probleme avec scanf

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

probleme avec scanf

n°703217
Alana
Amiga for ever.
Posté le 19-04-2004 à 21:12:20  profilanswer
 

Bonjour,
 
Petit probleme avec scanf donc.
En gros, le but du jeu est de saisir une chaine qui peut contenir des espaces. Si on met pas d'espace, tout se passe bien. Si on met des espaces, les scanf suivant sont "sautés".
 
En gros le code (j'abrege hein.. c'est pas la syntaxe exacte) resemble a :
 
printf "entrez chaine1"
scanf (chaine1)
printf "entrez chaine2"
scanf (chaine2)
printf "entrez chaine3"  
scanf (chaine3)
etc.
 
Si pour chaine1, je repond par exemple "bidule chose"
alors chaine1 vaudra bidule, et chaine2 vaudra chose,
le prog saute directement sur le dernier scanf.
Moi je voudrai qu'il considere les espaces comme des caracteres normaux quoi...
 
Voila, j'espere que c'etait clair comme explication :D Si vous avez une solution...

mood
Publicité
Posté le 19-04-2004 à 21:12:20  profilanswer
 

n°703221
Taz
bisounours-codeur
Posté le 19-04-2004 à 21:17:29  profilanswer
 

printf("message sans \\n" );
fflush(stdout);
fgets(buffer, sizeof buffer, stdin);

n°703222
Le Mage
Posté le 19-04-2004 à 21:17:37  profilanswer
 

salut,
scanf coupe a chaque espace ou entrée.
La suite est dans la chaine parce que ca marche avec un buffer qui se vide de ce qui a été passé dans ta variable, donc il reste "chose".
Pour faire simple, fais avec gets().
Si tu veux utiliser scanf, rajoute fflush(stdin); avant chacun d'eux pour éviter les pb de ce type avec le buffer.


Message édité par Le Mage le 19-04-2004 à 21:19:01
n°703223
Taz
bisounours-codeur
Posté le 19-04-2004 à 21:18:45  profilanswer
 

Le Mage a écrit :

salut,
scanf coupe a chaque espace ou entrée.
La suite est dans la chaine parce que ca marche avec un buffer qui se vide de ce qui a été passé dans ta variable, donc il reste "chose".


buffer overflow -> erreur de segmentation

Le Mage a écrit :


Pour faire simple, fais avec gets().


buffer overflow -> erreur de segmentation

Le Mage a écrit :


Si tu veux utiliser scanf, rajoute fflush(stdin); avant chacun d'eux pour éviter les pb de ce type avec le buffer.

aucun effet. t'as besoin de retourner à l'école toi


Message édité par Taz le 19-04-2004 à 21:19:03
n°703225
Alana
Amiga for ever.
Posté le 19-04-2004 à 21:20:05  profilanswer
 

Merci a vous deux, avec ca elle devrait y arriver....  
(moi le C j'avoue que ca fait un moment que j'en avait pas fait :D )

n°703227
Taz
bisounours-codeur
Posté le 19-04-2004 à 21:21:45  profilanswer
 

merci à moi, si tu suis les conseils du mage, ça ne marchera jamais

n°703228
Alana
Amiga for ever.
Posté le 19-04-2004 à 21:24:01  profilanswer
 

Taz : j'ai bien ton approche mais :
- Tu peux m'expliquer pourquoi on pourait pas mettre de \n a la fin du printf ? (désole j'ai l'impression de poser des questions bete la....)
- Y a pas moyen de faire ca avec un gets plutot qu'un fgets ? Enfin disons y a pas moyen de faire ca avec une syntaxe plus facile a comprendre ? Parce que c'est pour un programme de debutant en C, ils ont pas encore appris les stream, ni les malloc etc, bref, ils utilise que des tableaux pour leur chaine de caractere, je sens que si elle fait un truc aussi bien, avec un sizeof au milieu de la commande, ca va pas le faire...

n°703230
Taz
bisounours-codeur
Posté le 19-04-2004 à 21:29:10  profilanswer
 

1) si tu ne force pas le rafraichissement de ton écran avec ton prompt, tu risque de voir d'abord le prompt, ensuite le message t'invitant à saisir une donnée. si le printf avec ton scanf se termine par un '\n', à cause du mode de bufferisation, tu n'a pas besoin de rafraichir manuellement, ça se fera tout seul
2) avec gets, si tu as un char[5] et que tu en saisi 10, ça va faire boom. avec fgets, tu spécifies le maximum de caractères à prendre, comme ça tu ne risques pas de dépassement de capacité.
 
vrai programme
 

Code :
  1. #include <stdio.h>
  2. int main()
  3. {
  4.   char buffer[40];
  5.   printf("prompt :" );
  6.   fflush(stdout);
  7.   fgets(buffer, sizeof buffer, stdin);
  8.   puts(buffer);
  9.   return 0;
  10. }

note que sizeof buffer == 40, c'est juste un raccourci pour éviter les erreurs de typo et autre puisqu'apèrs tout, on ne veut pas lire 40caractères, mais plutot autant de caractère que peut contenir le buffer

n°703232
Taz
bisounours-codeur
Posté le 19-04-2004 à 21:30:26  profilanswer
 

char * fgets (char * s, int size, FILE * stream);
 
 
fgets renvoie NULL s'il y a une erreur
avec s le buffer d'entrée
size la taille du buffer d'entrée
stream le flux à lire

n°703236
Alana
Amiga for ever.
Posté le 19-04-2004 à 21:37:23  profilanswer
 

Vi j'avais bien compris le principe, je voulais juste savoir si on pouvait pas faire tout aussi secure avec des commandes plus "simples". Mais bon, si pour eviter les buffer overflow y a pas le choix et qu'on est forcé de preciser la taille, ok, je vais lui conseiller ca.
Un immense merci.

mood
Publicité
Posté le 19-04-2004 à 21:37:23  profilanswer
 

n°703239
Le Mage
Posté le 19-04-2004 à 21:42:54  profilanswer
 

Au lieu de casser tout le monde comme je viens de le voir sur d'autres post Taz, tu aurais pu remarquer le "pour faire simple" avant la suggestion du gets() vu qu'alana a l'air de débuter et faire juste qq tests.
Cela dit, le fflush(stdin); vide le buffer de SAISIE, tous les profs le conseille en C.

n°703240
Taz
bisounours-codeur
Posté le 19-04-2004 à 21:43:04  profilanswer
 

ben en C, tu peux pas passer un tableau tel quel en paramètre, donc tu doit passer le tableau automatiquement converti en pointeur + sa taille. ça fait 2 paramètres déjà. après le flux, ici, stdin, le flux d'entrée standard ... rien de bien méchant. c'est sur que gets(char *buffer) aurait du être gets(char *buffer, size_t size) <-> fgets(buffer, size, stdin) mais c'est comme ça :/

n°703243
skelter
Posté le 19-04-2004 à 21:48:41  profilanswer
 

Le Mage ==> il est dit dans le k&r ansi que un fflush sur un input stream a un effet indefinis alors tu peux dir a t prof d'arreter de dir des connerie

n°703244
chaica
Posté le 19-04-2004 à 21:49:18  profilanswer
 

skelter a écrit :

Le Mage ==> il est dit dans le k&r ansi que un fflush sur un input stream a un effet indefinis alors tu peux dir a t prof d'arreter de dir des connerie


 
Je me suis fait grilled d'une force :D à la citation près.

n°703246
skelter
Posté le 19-04-2004 à 21:51:26  profilanswer
 

oui faut etre plus rapide :d

n°703252
Le Mage
Posté le 19-04-2004 à 21:57:07  profilanswer
 

je maintiens que pour les trucs basiques ca marche.
Apres, pour des manips + compliquées, je suis d'accord que ca a des ratés comme strcpy et la plupart des fonctions sur les chaines qui ont des effets de bords.

n°703256
Taz
bisounours-codeur
Posté le 19-04-2004 à 21:59:56  profilanswer
 

Le Mage a écrit :

je maintiens que pour les trucs basiques ca marche.
Apres, pour des manips + compliquées, je suis d'accord que ca a des ratés comme strcpy et la plupart des fonctions sur les chaines qui ont des effets de bords.

1) non
2) non et c'est dangereux.
 
je crois que tous les compilateurs qui se valent emettent un warning si on utilise gets :o

n°703260
Le Mage
Posté le 19-04-2004 à 22:04:51  profilanswer
 

Je répète que G donné çà "pour faire simple", je l'utilise jamais et j'utilise tt le tps fgets.

n°703261
Taz
bisounours-codeur
Posté le 19-04-2004 à 22:05:58  profilanswer
 

Le Mage a écrit :

Je répète que G donné çà "pour faire simple", je l'utilise jamais et j'utilise tt le tps fgets.

y a pas de "pour faire simple"
1) il ne faut jamais utiliser gets
2) fflush(stdin) n'a aucun effet comme déjà expliqué

n°703262
Le Mage
Posté le 19-04-2004 à 22:09:38  profilanswer
 

Enfin, je reconnais bien là le cliché du programmeur acharné et toujours agréable qd il explique (cf autres posts sur le même thème).
J'insiste pas.

n°703263
Taz
bisounours-codeur
Posté le 19-04-2004 à 22:11:42  profilanswer
 

- gets est __la__ fonction à banir du C
- fflush(stdin) est un des plus gros mythe qui soit
 
 
et toi tu débarques et tu refiles ça à un débutant... t'attends pas à de bonnes réactions

n°703268
skelter
Posté le 19-04-2004 à 22:20:28  profilanswer
 

j'ai chercher sur internet et des fflush(stdin) on en voit partout (tuto, cours, exemple, ...)
 
inquietant non?

n°703275
Taz
bisounours-codeur
Posté le 19-04-2004 à 22:32:29  profilanswer
 

Taz a écrit :

- fflush(stdin) est un des plus gros mythe qui soit

dieu^k&r est mort. les gens ne croient plus en rien, on est plus beaucoup à penser que pour apprendre le C il faut lire le k&r

n°703281
skelter
Posté le 19-04-2004 à 22:43:01  profilanswer
 

oui, ca j'imagine, en fait qd on regarde bien rare sont les tutos qui respecte le standard ansi, ne serait-ce que pour les commentaires  "//" omniresent
 
j'ai trouver un lien qui pointe sur des codes en vieux c (k&r pre ansi) marrant a voir
 
si ca interresse qq1
 
http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html


Message édité par skelter le 19-04-2004 à 22:44:19
n°703331
Alana
Amiga for ever.
Posté le 19-04-2004 à 23:57:23  profilanswer
 

Whaou.. je vois que ca declanche un debat passioné...
bon merci encore Taz, car j'aprouve ton coté heu... on va dire extremiste ;)
Par contre le bout de code que tu m'a filé ne marche pas.
j'avoue que ca m'a un peu enervé, mais en fait je viens de comprendre pourquoi. Il semblerait que la fonction fflush ne fonctione pas sous linux. (j'avais pas precisé que c'etait sous linux mais bon.. je pensai pas une seconde que pour un truc aussi basique ca pouvait avoir de l'importance).
Donc voila sous linux c'est plus le bordel apparament.
Donc si t'a une autre reponse, plus unixiene on va dire, hesite pas :)

n°703333
Taz
bisounours-codeur
Posté le 20-04-2004 à 00:00:35  profilanswer
 

y a quoi qui marche pas ? le bout de code que je t'ai filé fonctionne parfaitement. tu te rends compte de ce que tu sors : tu fais du C depuis 1h et tu remets un cause une fonction de la bibliothèqye qui a plus de 20ans "hey elle bug cette fonction, c'est de la merde" ?
faut être un peu sérieux. le petit bout de code que je t'ai donné fonctionne parfaitement. maintenant si ton programmes fonctionne mal, c'est que tu as d'autres endroits qui ne doivent pas être très sains

n°703345
Alana
Amiga for ever.
Posté le 20-04-2004 à 00:28:39  profilanswer
 

Hé Du calme :( Je te dis juste ce que je constate, et ce que pretend le prof de ma femme (je t'ai dit c'est pas moi qui fait le programme). Et donc ce monsieur pretend que fflush fonctionne pas sous linux, il se goure peut etre completement, j'en sais fichtrement rien moi. Si tu m'affirme que ca fonctionne tout aussi bien sous linux et que tu as pu le verifier, je te crois. Maitenant mon probleme c'est que le premier fgets recupere un \n qui vient de je sais pas ou. Pour la suite par contre ca marche parfaitement.
 
Donc bein voila. Si tu m'affirme que ca fonctionne tout pareil sous linux, je vais continuer a me pencher sur le code pour essayer de comprendre d'ou pourait bien venir ce fichu \n. Sinon elle va suivre les recomandations de son prof (ultra lourdingues) qui consistent a reecrire la fonction fsgets a coup de getchar en gros. (vraiment pas top donc)

n°703347
Taz
bisounours-codeur
Posté le 20-04-2004 à 00:31:00  profilanswer
 

ben quand tu saisis "dawa" au clavier, tu valides et hop y a un '\n' qui est balancé. donc oui tu le récupères évidemment. c'est écris dans la documentation.
 
tu veux l'enlever ? ben tu mets un '\0' à la place et voilà

n°703348
Taz
bisounours-codeur
Posté le 20-04-2004 à 00:35:38  profilanswer
 

faut vraiment tout faire ici
 

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. char *my_gets(char *buffer, size_t size)
  5. {
  6.   char *eol = NULL;
  7.   if(!fgets(buffer, size, stdin))
  8.     return NULL;
  9.   eol = strrchr(buffer, '\n');
  10.   if(eol)
  11.     *eol = '\0';
  12.   return buffer;
  13. }
  14. int main()
  15. {
  16.   char buffer[40];
  17.    
  18.   printf("prompt : " );
  19.   fflush(stdout);
  20.   my_gets(buffer, sizeof buffer);
  21.   printf("\"%s\"", buffer);
  22.   return 0;
  23. }


Message édité par Taz le 20-04-2004 à 00:37:37
n°703349
Taz
bisounours-codeur
Posté le 20-04-2004 à 00:39:13  profilanswer
 

juste pour l'histoire : je m'applique a toujours donné du code du plus pur standard c'est à dire qui fonctionne parfaitement de manière identique partout où il y a un compilateur qui respecte la norme. le prof de ta femme est un amateur, un mauvais pédagogue, un ignorant.

n°703352
Alana
Amiga for ever.
Posté le 20-04-2004 à 00:41:22  profilanswer
 

Bein c'etait ce qu'elle etait en train d'ecrire. Merci donc de lui confirmer que c'est bien comme ca qu'il faut faire. J'avoue que je comprend un peu son etonement, tout ce code la pour faire un simple scanf qui fonctionne, t'avouera qu'on a déja fait plus ergonomique...

n°703355
Taz
bisounours-codeur
Posté le 20-04-2004 à 00:45:45  profilanswer
 

rien à voir.
scanf -> pas (ou mauvaise) gestion des dépassement de capacité
-> impossible de lire une ligne, scanf lit jusqu'au premier blanc, c'est à dire un seul mot.
 
le fflush est une autre chose qui est compréhensible, les terminaux étant bufferisés en mode ligne
 
tu veux pas du '\n' qui est naturellement dans stdin puisque tu le tappes ? il te suffit de l'enlever.
 
ça reste du C. bien arrangé dans une jolie fonction, ça redevient sure, efficace et simple à utiliser.

n°703357
Alana
Amiga for ever.
Posté le 20-04-2004 à 00:47:06  profilanswer
 

Citation :


le prof de ta femme est un amateur, un mauvais pédagogue, un ignorant.


 
Meme si je trouve completement anormal qu'il ai apparement pas parlé du probleme des buffer overflow, et encore plus anormal qu'il commence par filer des commandes dangereuses, je me met a sa place. Serieusmeent si je devai faire un cours en C, et si la premiere chose que je disai a mes eleves c'est que pour faire l'equivalent d'un input "nom :";A$ il faut plus de 20 lignes de code, je pense pas que mon cours ai beaucoup de succes et je pense que les elevs auraient vite laissé tombé.
 
Bref, c'est pas parce qu'UN prof enseigne pas un C ultra pur qu'il faut te mettre dans tes etats :D J'ai été impressioné par le nombre de bons profs qu'elle a, et par leur niveau global (ainsi que par leur large support de tout ce qui est open source).
 
Quand tu explique un truc a quelqu'un il faut deux choses, la connaissance technique, et un peu de pedagogie...
 
EDIT : j'ai édité car tout compte fait, je pense pas qu'il soit si mauvais que ca ce prof.


Message édité par Alana le 20-04-2004 à 09:33:42
n°703358
Alana
Amiga for ever.
Posté le 20-04-2004 à 00:48:14  profilanswer
 

Gasp, t'a été plus rapide que moi. Je pensai a strcpy et j'ai edité mon post, mais trop tard :D

n°703360
Taz
bisounours-codeur
Posté le 20-04-2004 à 00:50:32  profilanswer
 

euh je vois pas de quoi tu parles pour strcpy ? elle est dans quelle fac ta femme ? quelle formation ?
 
ce n'est pas une question d'être à jour. le C a toujours était comme ça. le créateur du C t'aurais à peu près suggéré la même chose que moi.

n°703361
Alana
Amiga for ever.
Posté le 20-04-2004 à 00:51:56  profilanswer
 

Je parle de strcpy parce que c'est, il me semble, l'une des fonction a surtout pas utiliser pour faire du code secure, et tu semblait, comme moi, apporter une grande importance a cet aspect des choses.


Message édité par Alana le 20-04-2004 à 00:58:06
n°703362
Taz
bisounours-codeur
Posté le 20-04-2004 à 00:56:13  profilanswer
 

strcpy peut en effet poser problème, on lui préfère strncpy/strlcpy mais c'est c'est là un moindre mal. le problème avec strcpy, c'est que si dans strcpy(dest, src) src a un problème, à savoir n'a pas de '\0' terminal, là ça fait boom. si src est correctement formé et que dest est suffisemment large pour accueillir une copie des caractères de src, tout ira bien.
 
en fait strcpy n'est pas dangereuse en elle même, ça vient des ses paramètres. mais gets, elle, va lire tant et plus de telle sorte que tu feras un dépassement de capacité quelque soit la taille de ton buffer de lecture.

n°703363
Alana
Amiga for ever.
Posté le 20-04-2004 à 00:57:41  profilanswer
 

Je le note. Bon allez, dodo. Merci.

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  probleme avec scanf

 

Sujets relatifs
[CSS] Probleme d'affichage de taille de police sur IE5Problème de calcul de dates
Problème ACCESS et Recorsource[eclipse] probleme de visualisation de page JSP
Problème de pageProbleme de transfert de chaîne de caractere vers BDD.HELP!!!!
Petit probleme tout bete (printf/scanf)probleme de scanf("%s",&...)
[ C - Gros debutant ]Probleme de scanf[C - Linux] problème avec scanf
Plus de sujets relatifs à : probleme avec scanf


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR