Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème de compréhension du string

Sujet résolu
    30 novembre 2018 à 10:15:06

    Bonjour je suis en train de faire le tp du mot mystere, mais voila dans la fonction mélanger il y a quelque chose que je ne comprends pas.

    La bonne fonction est celle-ci :

    string melangerLettres(string mot)
    {
       string melange;
       int position(0);
    
       //Tant qu'on n'a pas extrait toutes les lettres du mot
       while (mot.size() != 0)
       {
          //On choisit un numéro de lettre au hasard dans le mot
          position = rand() % mot.size();
          //On ajoute la lettre dans le mot mélangé
          melange += mot[position];
          //On retire cette lettre du mot mystère
          //Pour ne pas la prendre une deuxième fois
            mot.erase(position, 1);
        }
    
       //On renvoie le mot mélangé
       return melange;
    }

    Voici ce que j'ai au niveau de la ligne 12:

    string melanger_lettre(string lettre_melange)   //Mellange des lettres
    {
        int i=0, position=0;
        string melange;
        for(i=0;i<5;i++)
        {
            position = rand() % lettre_melange.size();  //recupere la taille du mot mystere et tire une lettre au hasard
    
            
    		
    	cout << "Lettre au hasard :" << lettre_melange[position]<<endl;
            melange[i] = lettre_melange[position];
            cout<<"Lettre"<<melange[i]<<endl;
            lettre_melange.erase(position, 1);  // Retire la lettre n°5
            cout<<"Le mot mystere est : "<<lettre_melange<<endl;
            cout<<"Le mot melange est : "<<melange<<endl;
    
    
        }
    
        cout<<"Le mot melange est : "<<melange<<endl;
    
    
        return melange;
    }


    Mon problème se situe seulement sur la ligne 12 que je ne comprend.

    Pourriez vous m'expliquer ce que fais la ligne 12 du premier code et pourquoi la ligne du deuxième code ne fonctionne pas.

    -
    Edité par TomGuy 30 novembre 2018 à 10:19:35

    • Partager sur Facebook
    • Partager sur Twitter
      30 novembre 2018 à 10:58:44

      += ---> Ajout

      Example :

      String foo = "bar";
      
      foo += "lorem";
      
      std::cout << foo;
      
      OUTPUT :
      barlorem


      • Partager sur Facebook
      • Partager sur Twitter
        30 novembre 2018 à 11:09:51

        Garfounk a écrit:

        += ---> Ajout

        Example :

        String foo = "bar";
        
        foo += "lorem";
        
        std::cout << foo;
        

        OUTPUT :

        barlorem


        D'accord donc en fait ça se comporte comme une concaténation.

        Mais alors dans le deuxième code, un string c'est bien un tableau non ? alors pk je n'arrive pas à afficher le mot mélangé correctement.



        • Partager sur Facebook
        • Partager sur Twitter
          30 novembre 2018 à 11:36:14

          TomGuy a écrit:

          D'accord donc en fait ça se comporte comme une concaténation.


          Dans le cas d'une String, oui.

          TomGuy a écrit:

          Mais alors dans le deuxième code, un string c'est bien un tableau non ? alors pk je n'arrive pas à afficher le mot mélangé correctement.

          Et un tableau c'est un pointeur sur l'index 0 et une taille.

          print une String, c'est print tout les charactères à partir de l'adresse définie comme "l'index 0" jusqu'au prochain '\0' qui définit la fin d'une String.

          Lorsque tu écrit :

          std::string test = "chocolat";

          On a :

          • test[0] = c
          • test[1] = h
          • test[2] = o
          • test[3] = c
          • test[4] = o
          • test[5] = l
          • test[6] = a
          • test[7] = t
          • test[8] = \0 --> Fin de la string. Tu ne le vois pas mais le compilateur ajoute automatiquement un '\0' pour définir la fin de la String.
          Donc, si tu écris :
          std::string melange;
          Le compilateur ne connaît pas la taille de la string et ne saura pas où mettre le `\0'. Si tu essayes de print cette String, il retrouvera bien l'index 0 mais il va continuer de print tout les charactères en mémoire jusqu'à ce qu'il arrive sur un \0 quelconque, mis ici par hasard. ça peut aussi bien être dès le premier characètre (l'index 0 donc) ou bien après 20 000 charactères par exemple.
          Donc première chose : lorsque tu déclares une string fais le de cette façon
          std::string melange = "";

          Aussi, as-tu essayé ton code avec un mot plus petit ? Un mot de deux lettres par exemple ???

          -
          Edité par Garfounk 30 novembre 2018 à 11:41:53

          • Partager sur Facebook
          • Partager sur Twitter
            30 novembre 2018 à 12:43:52

            Garfounk a écrit:

            TomGuy a écrit:

            D'accord donc en fait ça se comporte comme une concaténation.


            Dans le cas d'une String, oui.

            TomGuy a écrit:

            Mais alors dans le deuxième code, un string c'est bien un tableau non ? alors pk je n'arrive pas à afficher le mot mélangé correctement.

            Et un tableau c'est un pointeur sur l'index 0 et une taille.

            print une String, c'est print tout les charactères à partir de l'adresse définie comme "l'index 0" jusqu'au prochain '\0' qui définit la fin d'une String.

            Lorsque tu écrit :

            std::string test = "chocolat";

            On a :

            • test[0] = c
            • test[1] = h
            • test[2] = o
            • test[3] = c
            • test[4] = o
            • test[5] = l
            • test[6] = a
            • test[7] = t
            • test[8] = \0 --> Fin de la string. Tu ne le vois pas mais le compilateur ajoute automatiquement un '\0' pour définir la fin de la String.
            Donc, si tu écris :
            std::string melange;
            Le compilateur ne connaît pas la taille de la string et ne saura pas où mettre le `\0'. Si tu essayes de print cette String, il retrouvera bien l'index 0 mais il va continuer de print tout les charactères en mémoire jusqu'à ce qu'il arrive sur un \0 quelconque, mis ici par hasard. ça peut aussi bien être dès le premier characètre (l'index 0 donc) ou bien après 20 000 charactères par exemple.
            Donc première chose : lorsque tu déclares une string fais le de cette façon
            std::string melange = "";

            Aussi, as-tu essayé ton code avec un mot plus petit ? Un mot de deux lettres par exemple ???

            -
            Edité par Garfounk il y a environ 1 heure

            D'accord merci pour tes explications.

            Et oui entre temps j'ai modifié mon programme afin de pouvoir mettre de mots d'un taille différente de 5.

            • Partager sur Facebook
            • Partager sur Twitter
              30 novembre 2018 à 13:36:20

              Garfounk a écrit:

              Et un tableau c'est un pointeur sur l'index 0 et une taille.

              print une String, c'est print tout les charactères à partir de l'adresse définie comme "l'index 0" jusqu'au prochain '\0' qui définit la fin d'une String.

              Lorsque tu écrit :

              std::string test = "chocolat";

              On a :

              • test[0] = c
              • test[1] = h
              • test[2] = o
              • test[3] = c
              • test[4] = o
              • test[5] = l
              • test[6] = a
              • test[7] = t
              • test[8] = \0 --> Fin de la string. Tu ne le vois pas mais le compilateur ajoute automatiquement un '\0' pour définir la fin de la String.
              Donc, si tu écris :
              std::string melange;
              Le compilateur ne connaît pas la taille de la string et ne saura pas où mettre le `\0'. Si tu essayes de print cette String, il retrouvera bien l'index 0 mais il va continuer de print tout les charactères en mémoire jusqu'à ce qu'il arrive sur un \0 quelconque, mis ici par hasard. ça peut aussi bien être dès le premier characètre (l'index 0 donc) ou bien après 20 000 charactères par exemple.

              Tu ne confondrais pas les std::string et les cstring du langage C?

              La manière dont sont mémorisés les caractères dans une std::string n'a normalement pas besoin d'être connue. c'est d'ailleurs une partie privée de la classe.

              On peut en fait pointer la zone de stockage des caractères, mais rien ne garantit qu'on y trouve un zéro terminal.



              -
              Edité par zoup 30 novembre 2018 à 13:37:30

              • Partager sur Facebook
              • Partager sur Twitter
                30 novembre 2018 à 14:06:07

                Garfounk a écrit:

                Donc, si tu écris :
                std::string melange;
                Le compilateur ne connaît pas la taille de la string et ne saura pas où mettre le `\0'. 

                La façon dont C++ gère la fin des chaines, on s'en cogne !!
                La fonction membres size(), les itérateurs, les algos de la librairie standard, ect ... sont la pour ça.
                Et par defaut, une chaine est initialisée à vide.

                Les chaines sont des objets, leurs comportement n'est pas tout à fait le même que les types élémentaires.

                -
                Edité par Deedolith 30 novembre 2018 à 14:09:14

                • Partager sur Facebook
                • Partager sur Twitter
                  30 novembre 2018 à 20:36:00

                  > La manière dont sont mémorisés les caractères dans une std::string n'a normalement pas besoin d'être connue. c'est d'ailleurs une partie privée de la classe. > > On peut en fait pointer la zone de stockage des caractères, mais rien ne garantit qu'on y trouve un zéro terminal.

                  En fait la norme donne des directives:

                  • Les caractères sont contigus en mémoire, mais on ne sait pas où ils seront stockés (en réalité il n'y a que 2 endroits possible: dans la pile de l'objet pour les petites chaîne (SSO), ou via l'allocateur)
                  • s[s.size()] fait toujours référence à un caractère nul -> zéro terminal (qu'il ne faut pas modifier). C'est le seul conteneur qui accepte les indices à la position size() plutôt que size()-1.

                  folly::string (la bibliothèque de Facebook) ne met le caractère 0 qu'à l'appel de c_str(), ce qui est plus efficace. Son implémentation du SSO supporte aussi plus de caractère.

                  > print une String, c'est print tout les charactères à partir de l'adresse définie comme "l'index 0" jusqu'au prochain '\0' qui définit la fin d'une String.

                  Non. std::string se fiche qu'il y a des caractères nuls au milieu de la chaîne¹, il garantit juste la présence d'un zéro terminal en fin. Donc à moins d'utiliser le pointeur directement (data() ou c_str()), l'affichage avec un flux c++ se fait avec la taille complète de la chaîne, c’est-à-dire s.size(). Par contre, le dispositif d'affichage peut considérer le zéro terminal comme une fin d'affichage de ligne.

                  ¹ pour avoir des caractères nul, il faut soit ajouter un char nul (s += '\0') soit en mettant explicitement la taille des chaînes qui contiennent un caractère nul.

                  • Partager sur Facebook
                  • Partager sur Twitter

                  Problème de compréhension du string

                  × 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