Partage
  • Partager sur Facebook
  • Partager sur Twitter

une alternative au code strcat

exercice de m@teo21

Sujet résolu
    27 novembre 2008 à 18:59:59

    Et bien, bonjour à tous :)
    Je n'ai pas l'habitude de poster sur un forum d'informatique, mais là j'ai comme qui dirait besoin d'un coup de main :-°
    Enfaite, dans l'exercice de m@teo21 où l'on doit retaper une fonction similaire à strcat, je n'arrive à la réécrire autrement qu'en incluant dans la fonction l'autre fonction "strlen". Mais je voudrais trouver une alternative en utilisant une condition! Est-ce possible?

    allez, je tente le coup avec ça :euh:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    	
    char* Concat(char* chaine1, const char* chaine2);
    
    int main(void)
    {
        char chaine1[100] = "texte ",chaine2[] = " pourri";
    
        Concat(chaine1, chaine2);
    
        printf("chaine1 vaut : %s\n", chaine1);
        printf("chaine2 vaut toujours : %s\n", chaine2);
      system ("PAUSE");
        return 0;
    }
    
    char* Concat(char* chaine1, const char* chaine2)
    {
    long i = 0, k = 0;
        do{
              if (chaine1[i]== '\0')//si chaine1 arrive à '\0'...
              {
               for ( chaine2[k] != '\0'; i++; k++ ) //...rajouter chaine2 à la suite de chaine1
            chaine1[i] = chaine2[k];
    }
    else //sinon, incrémenter pour que chaine1 arrive à '\0'
    {
     i++;   
    }                         
                             
    } while (chaine2[k] != '\0'); //répéter la boucle jusqu'à la fin de chaine2
    
        return chaine1; // renvoyer la chaine 1
    }
    


    bon raté, même Flash n'aurait pas le temps de lire mon programme :p (NOTEZ: je suis ultra-débutant, c'est pourquoi on retrouve tous ces trucs compliqués genre "un for dans un if lui-même dans un do...while" :D )
    je n'ai que 2 semaines de C derrière moi ^^

    une solution pour mon code (en gardant la même structure!)?
    • Partager sur Facebook
    • Partager sur Twitter
      27 novembre 2008 à 20:04:01

      Salut !
      Il faudrait que tu indentes correctement ton code afin de gagner en lisibilité.

      Sinon, tu crées une fonction Concat qui est sensée renvoyer un char*.
      Cependant, lors de l'appel à cette fonction, tu ne récupères pas ce qu'elle retourne.

      Je pense que tu devrais revoir la syntaxe de ton for : il n'y a pas de condition d'arrêt...

      Bonne soirée & bon courage !
      • Partager sur Facebook
      • Partager sur Twitter
        28 novembre 2008 à 19:03:54

        salut, et merci de ta réponse!

        bon, j'ai toujours été bordélique, mais j'ai essayé de quand même mettre un peu d'ordre dans mon code. quand tu dis de revoir ma boucle for, enfaite, je devais juste ajouter ";"? c'était une inattention de débutant :D
        donc ça donne:

        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        	
        
        char* Concat(char* chaine1, const char* chaine2);
        
        int main(void)
        {
            char chaine1[100] = "texte ", chaine2[] = " pourri";
         
            printf("chaine1 vaut : %s\n", chaine1);
        
            Concat(chaine1, chaine2);
        
            printf("chaine1 vaut maintenant: %s\n", chaine1);
            printf("chaine2 vaut toujours : %s\n", chaine2);
          system ("PAUSE");
            return 0;
        }
        
        char* Concat(char* chaine1, const char* chaine2)
        {
            long i = 0, k = 0;
        do{
            
        if (chaine1[i]== '\0')//si chaine1 arrive à '\0'...
        {
        	
        for(; chaine2[k] != '\0' ; i++, k++) //...rajouter chaine2 à la suite de chaine1
            chaine1[i] = chaine2[k];
             }
        else //sinon, incrémenter pour que chaine1 arrive à '\0'
        {
            i++;   
              }                         
                                 
        }while (chaine2[k] != '\0'); //répéter la boucle jusqu'à la fin de chaine2
        
        return chaine1; // renvoyer la chaine 1
        
        
        }
        


        hallelujah, franchement là je m'y attendais pas :o Je croyais que j'étais loin de la vérité mais enfaite il manquait juste un ";" ?!

        Citation : bloodydark

        Cependant, lors de l'appel à cette fonction, tu ne récupères pas ce qu'elle retourne.



        Gné? je ne te suis pas là, j'ai rien changer à ce niveau et le code fonctionne o_O
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          28 novembre 2008 à 23:01:12

          raphamil VS merodrem :

          raphamil:

          char* cat(char* s1, const char* s2) {
              if(s2 == NULL || s1 == NULL) return NULL;
              for(; *s1; ++s1);
              for(; *s2; *s1++ = *s2++);
              return s1;
          }
          


          => 5 lines

          merofrem :

          char* Concat(char* chaine1, const char* chaine2)
          {
              long i = 0, k = 0;
          do{
              
          if (chaine1[i]== '\0')//si chaine1 arrive à '\0'...
          {
          	
          for(; chaine2[k] != '\0' ; i++, k++) //...rajouter chaine2 à la suite de chaine1
              chaine1[i] = chaine2[k];
               }
          else //sinon, incrémenter pour que chaine1 arrive à '\0'
          {
              i++;   
                }                         
                                   
          }while (chaine2[k] != '\0'); //répéter la boucle jusqu'à la fin de chaine2
          
          return chaine1; // renvoyer la chaine 1
          
          
          }
          


          => 22 lines

          And the winner is...

          raphamil !

          Il faut tu apprennes à faire des codes plus compacts pour mieux programmer en C ;)
          • Partager sur Facebook
          • Partager sur Twitter
            28 novembre 2008 à 23:12:01

            Un code plus compact n'est pas synonyme de "meilleur" code pour autant.
            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              28 novembre 2008 à 23:13:13

              Je sais. Mais le mien semble plus clair (donne-moi ton avis).
              • Partager sur Facebook
              • Partager sur Twitter
                28 novembre 2008 à 23:24:42

                Dans l'absolu il est clair que j'aurais codé à peu près de la même manière que toi si j'avais voulu faire très compact, même si par exemple le "return NULL" je l'aurais mis à la ligne, question de norme personnelle (et de lisibilité à mon sens).

                C'est du code efficace, mais c'est peut-etre pas le plus facile à lire.

                Un exemple d'implémentation claire que j'ai trouvé dans le man de strcat (là en fait c'est strncat) et qui aurait été semblable à un premier jet personnel :

                char*
                strncat(char *dest, const char *src, size_t n)
                {
                    size_t dest_len = strlen(dest);
                    size_t i;
                
                    for (i = 0 ; i < n && src[i] != '\0'; i++)
                        dest[dest_len + i] = src[i];
                    dest[dest_len + i] = '\0';
                    return dest;
                }
                


                Pas très compact mais tout aussi lisible. Vouloir compacter c'est bien je pense, mais trop nuit à la lisibilité de l'ensemble et la maintenance éventuelle à faire dessus. ;)
                • Partager sur Facebook
                • Partager sur Twitter
                  28 novembre 2008 à 23:37:59

                  1) ton code ne fonctionne pas comme prévu

                  2) De toute façon, si tu veux vraiment compacter, tu peux toutjours ecrire comme ca:
                  char*cat(char*s1,const char*s2){if(!s2||!s1)return NULL;for(;*s1;++s1);for(;*s2;*s1++=*s2++);return s1;}
                  

                  • Partager sur Facebook
                  • Partager sur Twitter
                    28 novembre 2008 à 23:44:31

                    J'avoue ne pas avoir vérifié le code, ça m'a semblé correct de loin mais la compacité ne m'a pas donné envie d'aller plus loin, en fait. :p

                    Et, personnellement, je préfère coder dans le style de l'exemple que j'ai donné. Les codes compacts sont vraiment trop ch***ts à lire et occasionnent bien plus d'erreurs.

                    Edit : oui en plus il retourne s1 qui a été modifié et qui doit pointer, si je ne m'abuse, sur le '\0' final de la chaine concaténée. C'est bien ce que je disais... :-°
                    • Partager sur Facebook
                    • Partager sur Twitter
                      29 novembre 2008 à 0:57:39

                      Citation : Eusebus


                      Un exemple d'implémentation claire que j'ai trouvé dans le man de strcat (là en fait c'est strncat) et qui aurait été semblable à un premier jet personnel :

                      char*
                      strncat(char *dest, const char *src, size_t n)
                      {
                          size_t dest_len = strlen(dest);
                          size_t i;
                      
                          for (i = 0 ; i < n && src[i] != '\0'; i++)
                              dest[dest_len + i] = src[i];
                          dest[dest_len + i] = '\0';
                          return dest;
                      }
                      



                      Pas très compact mais tout aussi lisible. Vouloir compacter c'est bien je pense, mais trop nuit à la lisibilité de l'ensemble et la maintenance éventuelle à faire dessus. ;)



                      Mauvaise (car inefficace pour une fonction de bibliothèque) implémentation de strcat, comme d'ailleurs le signale la page man en question :

                      An (very poor quality) implementation of strncat() could be

                      Il faut être lisible, absolument, en particulier si le code doit etre repris (par soi-meme ou quelqu'un d'autre). Il faut aussi etre efficace et connaitre ses gammes (K&R est un bon livre de solfège).

                      Citation : Floooder

                      1) ton code ne fonctionne pas comme prévu



                      C'est vrai mais je ne trouve pas correct de ne pas reconnaitre les qualités du code de raphamil qui est vraiment très joli par sa concision, meme Plauger fait moins bien dans son livre, donc je dis bravo à raphamil ou en tous cas, bravo à son code. Alors, il y a en effet une petite erreur et en outre, selon la norme, s1 et s2 ne sont pas censées etre le pointeur NULL. Ce qui donne le code suivant :

                      #include <stdio.h>
                      #include <string.h>
                      
                      char *cat(char *s1, const char *s2)
                      {
                        char *s = s1;
                      
                        for (; *s1; ++s1);
                        for (; *s2; *s1++ = *s2++);
                        return s;
                      }
                      
                      int main(void)
                      {
                        char s1[100] = "In code, ";
                        char t1[100] = "In code, ";
                        char *s2 = "we trust!";
                      
                        printf("cat : %s\n", cat(s1, s2));
                        printf("strcat : %s\n", strcat(t1, s2));
                      
                        return 0;
                      }
                      


                      cat : In code, we trust!
                      strcat : In code, we trust!


                      Voici l'implémentation que K&R proposent :


                      /* strcat: concatenate t to end of s; s must be big enough */ 
                      void strcat(char s[], char t[]) {
                      int i, j; 
                      i = j = 0; 
                      while (s[i] != '\0') /* find end of s */ 
                      i++; 
                      while ((s[i++] = t[j++]) != '\0') /* copy t */ 
                      ;
                      }
                      


                      • Partager sur Facebook
                      • Partager sur Twitter
                        29 novembre 2008 à 1:58:40

                        Dans ma page de man j'ai juste A simple implementation of strncat() might be: (page datée du 13/06/08).

                        Je n'ai fait que recopier ce que me disait ma page, et effectivement il y a largement mieux.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          29 novembre 2008 à 10:34:24

                          Citation : raphamil

                          And the winner is...

                          raphamil !



                          ok, sauf que le winner il a surement plus que mes 2 semaines de programmation derrière lui, je me trompe? ;)
                          Mais bon je peux encore condenser mon code:
                          char* Concat(char* chaine1, const char* chaine2)
                          {
                              long i = 0, k = 0;
                          do{   
                          if (chaine1[i]== '\0')
                          for(; chaine2[k] != '\0' ; i++, k++) 
                              chaine1[i] = chaine2[k];
                          else 
                              i++;                                                
                          }while (chaine2[k] != '\0'); 
                          return chaine1;
                          }
                          

                          ===> 12 lignes! Mais tout de suite moins clair à mes yeux...


                          Et puis, à mon niveau, j'aurais été capable de faire un code plus court, j'aurais surement inclus strlen dans ma fonction par exemple.

                          Et si tu relis mon premier message, tu verras que mon but était de refaire la fonction strcat avec une condition. Ton code fait 5 lignes, mai y a pas de conditions ^^
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Anonyme
                            29 novembre 2008 à 12:21:53

                            candide: Merci, ça fait chaud au coeur de voir son travail apprécié :) .
                            merodrem: J'ai environ 1 an de programmation derrière moi et le K&R dans ma bibliothèque, alors forcément...
                            • Partager sur Facebook
                            • Partager sur Twitter

                            une alternative au code strcat

                            × 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