Partage
  • Partager sur Facebook
  • Partager sur Twitter

Un '\n' enregistrer dans une chaine avec fgets

Sous linux ...

Sujet résolu
    6 juin 2006 à 21:37:05

    Voilà j'ai voulu progrmammer mon premier porgramme sous linux où je compile séparemment (sans IDE quoi !) donc c'était mon premier programme sous linux , j'ai fait un truc simple juste pour tester :
    #include <stdio.h>
    #include <stdlib.h>

    int main (int argc, char *argv[])
    {
      printf("Bienvenue !\n"
      char nom[100]={0};
      printf("Ton nom ? ");
      fgets(nom, sizeof(nom), stdin);
      printf("OK : ton nom est %s !\n\n", nom);
      printf("Appuyer sur une touche pour terminer\n");
      getchar();
      return EXIT_SUCCESS;
    }


    Et quand je le compile no probleme ni quand je l'exécute mais seulement quand j'entre 'Gertrude\n' (oui un autre nom ça fait pareil :p ) bah ça enregistre aussi mon entrée dans la chaine nom et donc ça fait une phrase toute moche avec le '!' sur une autre ligne. Comment éviter ça ?
    Pour infos ça m'est jamais arrivé sous Windows, comment ce fait-ce ?

    Merci d'avance ^^ !
    • Partager sur Facebook
    • Partager sur Twitter
      6 juin 2006 à 22:55:42

      Déjà, je ne sais pas si c'est sur le forum, mais ton printf n'est pas terminé ;)

      Ensuite, je pense que c'est normal qu'il enregistre le \n.

      Fais un test : réduis ta table a 10 caractères par exemple.
      Entre ensuite un mot de plus de 10 caractères. Surprise, il n'y a plus de saut de ligne. Normal, l'entrée est trop grande pour être lue entièrement, le dernier caractère est donc une lettre (ou un espace à la limite).
      (Note que dans ce cas, tu devrais lire les caractères non lus pour vider le buffer.)
      Dans le premier cas, l' \n était enregistré dans la chaîne.

      Il faut controler ce qu'on a entré quand on utilise fgets.

      A lire (-ed- te le dira lui aussi ;))
      http://mapage.noos.fr/emdel/
      Plus précisément:
      http://mapage.noos.fr/emdel/notes.htm#saisie
      http://mapage.noos.fr/emdel/notes.htm#fichiers
      • Partager sur Facebook
      • Partager sur Twitter
        6 juin 2006 à 23:08:04

        En effet, fgets enregistre le '\n'. gets ne le fait pas (de toute façon il ne faut pas l'utiliser). puts rajoute un '\n', mais fputs ne le fait pas. Je n'ai jamais compris la logique, mais c'est comme ça.

        Pour ton problème, le tableau nom est composée comme suit :
        'G', 'e', 'r', 't', 'r', 'u', 'd', 'e', '\n', 0, 0, ...

        C'est une chaîne de caractères, car c'est un tableau de char qui contient un 0. On peut donc lui appliquer strlen, ce qui renverra la longueur de la chaîne (donc le nombre de caractère non nuls précédant le premier zéros). Or tu peux remarquer (et prouver) que strlen renvoie également la position du premier zéro sur le tableau. Ici, ce qui te pose problème, c'est le dernier caractère non nul, c'est-à-dire le caractère situé juste avant ce premier zéro. Tu veux le supprimer, c'est-à-dire que tu aimerais que ce soit celui-ci qui soit le premier zéro. Ok ?

        La commande que tu cherches est :
        nom[strlen(nom) - 1] = 0;


        • Partager sur Facebook
        • Partager sur Twitter
          6 juin 2006 à 23:12:22

          Citation : yoxo

          Tu veux le supprimer, c'est-à-dire que tu aimerais que ce soit celui-ci qui soit le premier zéro. Ok ?

          La commande que tu cherches est :

          nom[strlen(nom) - 1] = 0;





          D'accord, mais si jamais il entre une chaîne plus longue que la capacité de sa variable. Là ça va foirer, il n'y aura pas d'\n enregistré, et tu virera ainsi le dernier caractère.

          Il faut mieux vérifier l'entrée comme c'est si bien expliqué dans les liens que j'ai donné ci-dessu.

          PS: Je sais que dans son essai, ta méthode va marcher, dans 99% des cas (si il laisse son char[100]), mais c'est pour prendre les bonnes habitudes.
          • Partager sur Facebook
          • Partager sur Twitter
            6 juin 2006 à 23:43:03

            Tout à fait. La commande que j'ai indiqué n'avait qu'une vocation informative et ne peut rigoureusement s'appliquer que si on est sûr que la taille de la chaine lue est inférieure à la taille du tableau. Ce qui n'est *pas* le cas sur une requête utilisateur.

            La solution d'Emmanuel (sur son site) est la bonne.
            • Partager sur Facebook
            • Partager sur Twitter
              7 juin 2006 à 8:19:13

              Merci pour ces réponses !
              COmment se fait-t-il cependant que ke scanf sur une chaîne n'enregistre pas le '\n' ?

              (Dsl si la réponse est dans les iens je n'ai pas encore eu le temps de les lires !)
              • Partager sur Facebook
              • Partager sur Twitter
                7 juin 2006 à 13:47:34

                Citation : Pierre89



                  printf("Bienvenue !\n"



                Merci de copier/coller et non de retaper avec des erreurs...

                Citation : Pas de titre


                Et quand je le compile no probleme ni quand je l'exécute mais seulement quand j'entre 'Gertrude\n' (oui un autre nom ça fait pareil :p ) bah ça enregistre aussi mon entrée dans la chaine nom et donc ça fait une phrase toute moche avec le '!' sur une autre ligne. Comment éviter ça ?
                Pour infos ça m'est jamais arrivé sous Windows, comment ce fait-ce ?


                Je te garantis que ça se comporte pareil sur toutes les machines (à moins que tu n'ais utilisé l'infâme et interdit gets())...

                Ce comportement est tout à fait normal, et il est expliqué dans le doc de fgets(). Il convient de 'nettoyer proprement' la ligne comme ceci :

                #include <stdio.h>
                #include <string.h>

                static void purge (FILE * fp)
                {
                   int c;
                   while ((c = fgetc (fp)) != '\n' && c != EOF)
                   {
                   }
                }

                static void clean (char *s, FILE * fp)
                {
                   /* search ... */
                   char *p = strchr (s, '\n')/* <string.h> */
                   if (p != NULL)
                   {
                      /* ... and kill */
                      *p = 0;
                   }
                   else
                   {
                      purge (fp);
                   }
                }

                int main ()
                {
                   printf("Bienvenue !\n");
                   char nom[100];
                   printf("Ton nom ? ");
                   fgets(nom, sizeof(nom), stdin);
                   clean(nom, stdin);
                   printf("OK : ton nom est %s!\n\n", nom);

                   return 0;
                }
                • Partager sur Facebook
                • Partager sur Twitter
                Music only !
                  7 juin 2006 à 14:14:16

                  Oui j'ai retesté sous Windows et ça faisait pareil !! J'ai bien lu ton site c'est bon j'ai compris.
                  Enfin j'ai bien fait un copier/coller mais j'ai dû me merder queqlque part :p !
                  Je mets en résolu.

                  Merci à tous
                  • Partager sur Facebook
                  • Partager sur Twitter
                    7 juin 2006 à 19:38:25

                    à la limite, tu aurais pu utiliser la fonction de M@teo dans le cours pour le pendu ^^
                    • Partager sur Facebook
                    • Partager sur Twitter

                    Un '\n' enregistrer dans une chaine avec fgets

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown