Partage
  • Partager sur Facebook
  • Partager sur Twitter

Les chaines de caractère en C

Un smiley et un autre caractere s'affiche en fin de chaine

Sujet résolu
    23 septembre 2022 à 5:00:06

    Salut !

    J'ai beau me casser la tête je ne trouve alors j'espère que vous pourrez m'aider.

    Alors voilà j'ai fait ce code:

    void buildSecretWord(char secretWordPointer[], const char wordPointer[])
    {
        for (int i = 0, j =0; i < strlen(wordPointer);) {
            if (*(&wordPointer[i]) != '\r' && *(&wordPointer[i]) != '\n' && *(&wordPointer[i]) != '\0')
            {
                *(&secretWordPointer[j]) = '*';
                j++;
            }
            i++;
            //printf("%c-%d_", *(&wordPointer[i]), i);
        }
            
        printf("%s", secretWordPointer); // doit afficher * autant de fois que le nombre de caractère de wordPointer
        SEPARATOR
    }

    Mais lorsque je fais mon printf parfois ça passe nickel et parfois beh ça me donne envie de lancer mon PC quand il me sort précisément ******☺f.

    le dernier caractère change constament, c'est pas toujours un 'f'.

    Jizen ni kansha

    • Partager sur Facebook
    • Partager sur Twitter

    <audio class="audio-for-speech" />

    Invalid imageright-arrow.pngInvalid image
    Fast traslate
    Icon translate
      23 septembre 2022 à 6:19:25

      Salut,

      Pose-toi cette question: En langage C, qu'est-ce qui caractérise une chaine de caractères ?

      Bonne continuation.

      _

      char a[] = "ABCD";                     /* string representation */
      char b[] = "\x41\x42\x43\x44";         /* hexadecimal representation */
      char c[] = "\101\102\103\104";         /* octal representation */
      char d[] = "A" "B" "C" "D";            /* using string properties */
      char e[] = {'A', 'B', 'C', 'D', '\0'}; /* using char property */

      -
      Edité par magma 23 septembre 2022 à 6:39:46

      • Partager sur Facebook
      • Partager sur Twitter
        23 septembre 2022 à 10:43:38

        Pourquoi ne pas utiliser la notation wordPointer[i] plutôt que *(&wordPointer[i]) ?  De même pour *(&secretWordPointer[j]).

        Quant à ton erreur, elle vient du format %s, qui est fait pour afficher les chaînes de caractères, pas les simples tableaux de caractères (d'où la question de magma).

        -
        Edité par robun 23 septembre 2022 à 10:44:25

        • Partager sur Facebook
        • Partager sur Twitter
          23 septembre 2022 à 11:16:52

          @SanaYasfp:

          Comme le dit robun, dans ta fonction *(&wordPointer[i]) se réfère exactement à la même chose que wordPointer[i], qui est bien plus simple à écrire... et, tant qu'à faire, une variable qui s'appelle simplement word est plus simple à écrire et lire.

          Ta fonction semble vouloir créer une chaîne de caractères à partir d'une autre, en supprimant les éventuels '\r ' et '\n' qu'elle contient et en remplaçant les caractères composant la chaîne, à l'exclusion du '\0' terminateur par une étoile.

          Dans ton code, tu ne termines pas ta nouvelle chaîne ainsi créée avec le caractère '\0'.

          Mettre strlen() dans la boucle for est maladroit et le type retourné par strlen() et adapté pour une variable utilisée en indice d'un tableau est size_t.

          En reprenant ton prototype de fonction, un exemple plus lisible et corrigeant ces différents problèmes peut être :

          #include <stdio.h>
          #include <string.h>
          
          void buildSecretWord(char secret[], const char word[]) {
                  size_t len = strlen(word);
                  size_t j = 0;
          
                  for (size_t i = 0; i < len; i++)
                          if (word[i] != '\r' && word[i] != '\n')
                                  secret[j++] = '*';
                  secret[j] = '\0';
          }
          
          int main(void) {
                  char secret[256] = { '\0' };
          
                  buildSecretWord(secret, "test");
                  printf("secret: %s\n", secret);
          
                  return 0;
          }
          

          -
          Edité par Dlks 23 septembre 2022 à 11:28:10

          • Partager sur Facebook
          • Partager sur Twitter
            23 septembre 2022 à 12:21:06

            Ce qui serait bien aussi, c'est de se débarasser des caractères \r \n, qui viennent de la saisie, mais sont des parasites dans le problème

            void nettoyer_mot(char mot[]) 
            {
               for (size_t i = 0; mot[i] != '\0'; i++) {
                   if (est_caractere_fin_ligne(mot[i]) {
                       mot[i] = '\0';
                       break;
                   }
            }
            
            // avec
            
            bool est_caractere_fin_ligne(char c) {
                return (c == '\r') || (c == '\n');
            }
            



            -
            Edité par michelbillaud 23 septembre 2022 à 12:21:37

            • Partager sur Facebook
            • Partager sur Twitter
              23 septembre 2022 à 12:42:33

              Ok je vois ! Arigato gozaimashita.

              @Dlks pourquoi ne pas garder le meme compteur pour la boucle et l'indice de secret comme ceci :

              #include <stdio.h>
              #include <string.h>
               
              void buildSecretWord(char secret[], const char word[]) {
                      size_t len = strlen(word);
                      size_t j = 0;
               
                      for (; j < len; j++)
                              if (word[j] != '\r' && word[j] != '\n')
                                      secret[j] = '*';
                      secret[j] = '\0';
              }
               
              int main(void) {
                      char secret[256] = { '\0' };
               
                      buildSecretWord(secret, "test");
                      printf("secret: %s\n", secret);
               
                      return 0;
              }
              • Partager sur Facebook
              • Partager sur Twitter

              <audio class="audio-for-speech" />

              Invalid imageright-arrow.pngInvalid image
              Fast traslate
              Icon translate
                23 septembre 2022 à 15:11:25

                Comme je disais à propos de ton code initial :

                Ta fonction semble vouloir créer une chaîne de caractères à partir d'une autre, en supprimant les éventuels '\r ' et '\n' qu'elle contient et en remplaçant les caractères composant la chaîne, à l'exclusion du '\0' terminateur par une étoile.

                car c'est ainsi que tu avais (tenté) de coder ta fonction.

                Là ton dernier code est bogué si la chaîne est susceptible de contenir ces caractères '\r ' et '\n', car le programme va simplement sauter les index correspondant à ces caractères et laissera la chaîne "secret" en l'état à ces emplacements.

                Essaye avec une chaîne de départ : "word\nwrap" au lieu de "test" pour comprendre.

                Avec le code que j'ai posté tu auras 8 étoiles, correspondant à : "wordwrap"

                Avec le code que tu as posté, comme "secret" est mis à 0 dans main, et que tu sautes l'emplacement où se trouve le '\n' tu auras 4 étoiles, correspondant à : "word" car la chaîne s'arrête là, cet emplacement n'ayant pas été écrasé dans la boucle, mais juste sauté, alors qu'il contient le caractère terminateur.

                -
                Edité par Dlks 23 septembre 2022 à 15:14:57

                • Partager sur Facebook
                • Partager sur Twitter
                  23 septembre 2022 à 15:19:12

                  Ça va marcher seulement si '\r' et '\n' sont à la fin et pas ailleurs.
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Le Tout est souvent plus grand que la somme de ses parties.

                    23 septembre 2022 à 15:24:51

                    @PierrotLeFou :

                    seulement si le tableau "secret" passé est initialisé à 0 dans main(), sinon, si les caractères '\r' et '\n' sont à la fin et sont "sautés" c'est potentiellement n'importe quoi qui sera affiché à la fin.

                    Aussi, on ne sait pas si la chaîne de départ vient d'une saisie (SanaYasfp ne nous le dit pas). Si c'est le cas, la saisie faite avec fgets() peut effectivement laisser '\n' à la fin, et pas au milieu de la chaîne. Il n'y en aurait qu'un au plus, et il y a des moyens plus directs de s'en débarrasser si on n'en veut pas.

                    -
                    Edité par Dlks 23 septembre 2022 à 15:32:11

                    • Partager sur Facebook
                    • Partager sur Twitter
                      23 septembre 2022 à 17:40:33

                      Dans son premier programme, SanaYasfp créait une deuxième chaîne à partir de la première en ajoutant une '*' à chaque fois que la première contenait un '\r' ou un '\n'. Par exemple si on part de "coucou\nme\rvoilà", la fonction crée "**".

                      SanaYasfp : ce n'est plus ça qu'il faut faire ?

                      • Partager sur Facebook
                      • Partager sur Twitter
                        23 septembre 2022 à 18:05:28

                        @robun: sauf erreur, le code ne faisait pas ce que tu décris.

                        #include <stdio.h>
                        #include <string.h>
                        
                        void buildSecretWord(char secretWordPointer[], const char wordPointer[]) {
                                for (int i = 0, j =0; i < strlen(wordPointer);) {
                                        if (*(&wordPointer[i]) != '\r' && *(&wordPointer[i]) != '\n' && *(&wordPointer[i]) != '\0') {
                                                *(&secretWordPointer[j]) = '*';
                                                j++;
                                        }
                                        i++;
                                }
                        }
                        
                        int main(void) {
                                char secret[256] = { '\0' };
                        
                                buildSecretWord(secret, "coucou\nme\rvoilà");
                        
                                printf("secret: %s\n", secret);
                        
                                return 0;
                        }
                        

                        donne chez moi :

                        $ gcc -g -Wall -Wextra make-star-word.c
                        make-star-word.c: In function ‘buildSecretWord’:
                        make-star-word.c:6:26: warning: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Wsign-compare]
                          for (int i = 0, j =0; i < strlen(wordPointer);) {
                                                  ^
                        $ ./a.out 
                        secret: **************
                        

                        -
                        Edité par Dlks 23 septembre 2022 à 18:06:43

                        • Partager sur Facebook
                        • Partager sur Twitter
                          23 septembre 2022 à 19:04:12

                          Ah oui, il fait le contraire !

                          (J'ai lu trop vite ces tests :

                          wordPointer[i]) != '\r'

                          ce n'est pas « égal à » mais « différent de ».)

                          -
                          Edité par robun 23 septembre 2022 à 19:07:11

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Les chaines de caractère en C

                          × 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