Probleme fgets

Probleme fgets - C - Programmation

Marsh Posté le 10-12-2004 à 00:28:47    

Bonjour, j'ai un probleme d'affichage avec fgets. J'essaie de recuperer une chaine de caracteres sur la sortie standard:
 

Code :
  1. int
  2. main()
  3. {
  4. int choix;
  5. printf("numero?" );
  6. fflush(stdout);
  7. scanf("%d",&choix);
  8. mafonction();
  9. }
  10. int
  11. get_line(char *buf, size_t size)
  12. {
  13.    int ret = 0;
  14.    if (fgets(buf, size, stdin) != NULL){
  15.       char *p = strchr(buf, '\n');
  16.       if (p != NULL){
  17.          *p = 0;
  18.          ret = 1;
  19.       }
  20.    }
  21.    return ret;
  22. }
  23. void
  24. mafonction()
  25. {
  26.    char *c;
  27.    c = (char *)malloc( TAILLE*sizeof(char) );
  28.    printf("Entrez une chaine de caracteres :" );
  29.    fflush(stdout);
  30.    if ( get_line(c, TAILLE) ){
  31.       printf("result=%s\n",c);
  32.       fflush(stdout);
  33.    }
  34.    else printf("Erreur!" );
  35.    
  36.    if ( c != NULL ){
  37.       printf("Liberation c\n" );
  38.       fflush(stdout);
  39.       free(c);
  40.    }
  41. }


 
Si dans ma fonction main(), je ne mets pas les 3 lignes printf,fflush et scanf avant l'appel de mafonction(), TOUT SE PASSE BIEN!
 
Dans le cas contraire, il passe directement toute la fonction sans me laisser ecrire, ce qui donne sur la sortie standard :  
"Entrez une chaine de caracteres :result="
 
De quoi cela vient il ?
 
Merci d'avance pour vos reponses..  

Reply

Marsh Posté le 10-12-2004 à 00:28:47   

Reply

Marsh Posté le 10-12-2004 à 00:58:31    

traduit en C sans se prendre le choux ton code se traduit par :

Code :
  1. #define _GNU_SOURCE
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. int main(void){
  6.   char * chaine;
  7.   size_t taille;
  8.   ssize_t retour;
  9.   int choix;
  10.   taille = 0;
  11.   chaine = NULL;
  12.   fprintf(stdout, "numero? : " );
  13.   if((retour = getline(&chaine, &taille, stdin)) == -1)
  14.     exit(1);
  15.   if((sscanf(chaine,"%d", &choix) != 1))
  16.     fprintf(stdout, "Erreur\n" );
  17.   free(chaine);
  18.   taille = 0;
  19.   chaine = NULL;
  20.   fprintf(stdout, "Entrez une chaine de caracteres : " );
  21.   if((retour = getline(&chaine, &taille, stdin)) == -1)
  22.     exit(1);
  23.   fprintf(stdout,"result=%s\n",chaine);
  24.   free(chaine);
  25.   return 0;
  26. }


Bon ok je triche en utilisant getline qui est GNU mais quand meme tu n'as pas un peu l'impression de te compliquer la vie avec scanf (qui est une verrue), fflush (??) etc...


Message édité par manatane le 10-12-2004 à 00:58:50
Reply

Marsh Posté le 10-12-2004 à 01:03:57    

Oui mais en fait j'ai absolument besoin de garder des fonctions en dehors de main().
 
Bon je vais essayer de changer ma ligne scanf.
 
Pour le fflush j'etais vraiment désespéée alors j'essyais un peu tout ;)

Reply

Marsh Posté le 10-12-2004 à 01:09:06    

en fait, c'est simple : quand tu lis en entier avec scanf. Toi tu tappes "69\n"  et scanf ne lis que le '6' et le '9'. Donc il reste des choses dans ton buffer de lecture.
 
 
Donc deux solutions simples:
- soit tu vides ce buffer jusqu'à l' '\n' -> http://www.isty-info.uvsq.fr/~rume [...] 4.html#q_5
- soit tu fais comme manatane, mais pas la peine d'utiliser getline. Tu lis une ligne avec fgets, et après tu l'analyse avec sscanf (même fonctionnement que scanf, sauf que le premier argument est la chaine contenant les données.

Reply

Marsh Posté le 10-12-2004 à 01:12:41    

ALors la merci beaucoup, je vais essayer tout de suite..
 
C'est quand même pas evident le C ;)

Reply

Marsh Posté le 10-12-2004 à 08:52:17    

myeve a écrit :

Bonjour, j'ai un probleme d'affichage avec fgets. J'essaie de recuperer une chaine de caracteres sur la sortie standard:
<...>
 
Si dans ma fonction main(), je ne mets pas les 3 lignes printf,fflush et scanf avant l'appel de mafonction(), TOUT SE PASSE BIEN!
 
Dans le cas contraire, il passe directement toute la fonction sans me laisser ecrire, ce qui donne sur la sortie standard :  
"Entrez une chaine de caracteres :result="
 
De quoi cela vient il ?
 
Merci d'avance pour vos reponses..


Déjà, ça, ça n'aide pas (je suppose qu'il s'agit d'un oubli).


Compiling MAIN.C:
Warning MAIN.C 5: Call to function 'printf' with no prototype
Error MAIN.C 6: Undefined symbol 'stdout'
Warning MAIN.C 6: Call to function 'fflush' with no prototype
Warning MAIN.C 7: Call to function 'scanf' with no prototype
Warning MAIN.C 8: Call to function 'mafonction' with no prototype
Warning MAIN.C 9: Function should return a value
Error MAIN.C 12: ) expected


Pour le reste, tu as écris une fonction get_line() qui est intéressante (je crois en reconnaître l'origine...héhé...), mais incomplète. En effet, elle ne traite pas le cas où la saisie est plus longue que la chaine. Dans ce cas, un '\n' traine dans stdin.
 
D'autre part, tu utilises scanf()  qui systématiquement laisse trainer un '\n' dans stdin. (fonction d'usage difficile peu recommandée)
 
http://mapage.noos.fr/emdel/notes.htm#saisie
 
ton utilisation de malloc() est compliquée :
 
http://mapage.noos.fr/emdel/notes.htm#malloc
 
et pas forcément justifiée ici (mais je suppose que c'est un exercice, au fait TAILLE n'est pas définie). De plus, il manque l'essentiel, à savoir le test de la valeur retournée par malloc() avant son utilisation.
 
sizeof(char) vaut 1 par définition.
 
Il est inutile de mettre fflush(stdout) si le texte envoyé à stdout est une ligne complète.
 
http://mapage.noos.fr/emdel/notes.htm#fflush_stdout
 
Voici ton code mis au point. Pose des questions si tu ne comprends pas.

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. int get_line (char *buf, size_t size)
  5. {
  6.    int ret = 0;
  7.    if (fgets (buf, size, stdin) != NULL)
  8.    {
  9.       char *p = strchr (buf, '\n');
  10.       if (p != NULL)
  11.       {
  12.          *p = 0;
  13.          ret = 1;
  14.       }
  15.       else
  16.       {
  17.          int c;
  18.          /* vider stdin proprement (ignorer les caracteres non lus) */
  19.          while ((c = getchar ()) != '\n' && c != EOF)
  20.          {
  21.          }
  22.       }
  23.    }
  24.    return ret;
  25. }
  26. void mafonction (void)
  27. {
  28.    size_t const TAILLE = 128;
  29.    char *c = malloc (TAILLE);
  30.    if (c != NULL)
  31.    {
  32.       printf ("Entrez une chaine de caracteres : " );
  33.       fflush (stdout);
  34.       if (get_line (c, TAILLE))
  35.       {
  36.          printf ("result=%s\n", c);
  37.       }
  38.       else
  39.       {
  40.          printf ("Erreur!\n" );
  41.       }
  42.       printf ("Liberation c\n" );
  43.       free (c);
  44.    }
  45. }
  46. int main ()
  47. {
  48.    int choix;
  49.    printf ("numero : " );
  50.    fflush (stdout);
  51.    {
  52.       char s[32];
  53.       get_line (s, sizeof s);
  54.       choix = (int) strtol (s, NULL, 10);
  55.    }
  56.    mafonction ();
  57.    return 0;
  58. }


Message édité par Emmanuel Delahaye le 10-12-2004 à 08:58:14

---------------
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 10-12-2004 à 09:53:42    

Emmanuel Delahaye a écrit :

Déjà, ça, ça n'aide pas (je suppose qu'il s'agit d'un oubli).

tu te souviens de ce que je t'ai dit à propos des devoirs

Reply

Marsh Posté le 10-12-2004 à 12:12:23    

Taz a écrit :

tu te souviens de ce que je t'ai dit à propos des devoirs


Oui, mais la bonne volonté du questionneur est évidente. C'est pas comme quand il poste 0 ligne de code en demandant de tout faire... Mais bon, si ce forum est strict à ce point, je vais me conformer... C'est frustrant...


Message édité par Emmanuel Delahaye le 10-12-2004 à 12:13:17

---------------
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 10-12-2004 à 14:34:35    

ce qu'il faut que tu vois bien, c'est que y a une fonction recherche sur le forum : y a des tas de topics remplis de bonnes choses. Et pour getline, la question est là toutes les semaines. Donc on essaie aussi de diminuer le rapport signal/bruit pour pas avoir 36 sujets sur la même chose. Les devoirs, attend un peu la rentrée de janvier : faut être ferme, sinon y a de l'abus :)

Reply

Sujets relatifs:

Leave a Replay

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