Partage
  • Partager sur Facebook
  • Partager sur Twitter

Inverser une chaine de caractère

Sujet résolu
    23 février 2022 à 23:23:04

    Bonjour, 

    Pour m'entrainer je travaille sur les chaines de caractères sans utiliser la librairie <string.h>. J'ai essayé d'écrire un programme qui inverse une chaine de caractère, comme un miroir. Par exemple, si j'écris "lynx", il renvoi "xnyl". Pour ça j'ai créé deux fonctions en plus de main : la première me donne le nombre de caractère de la chaine, aucun souci. C'est au niveau de la seconde fonction que ça coince.

    C'est elle qui est chargée de créer la chaine miroir et de la renvoyer à main. Je l'ai écrite pour qu'elle fonctionne ainsi : une variable i=0, et une seconde qui est égale à la longueur de la chaine originale (k). On fait donc chaine_miroir[i]=chaine_originale[k]. Donc le dernier terme de la chaine originale devient le premier de la chaine miroir. On fait i++ et k-- et après l'avant dernier terme de la chaine originale devient le second de la chaine_miroir et cela tant qu'on a pas fait tout les termes (j'ai opté pour une boucle While). Une fois cela fait, on renvoi chaine_miroir à main et on l'affiche.

    C'est là qu'est le problème : au lieu de m'afficher la chaine inversée, il m'affiche "(null)".

    J'ai fais des tests et on dirait que le souci est au niveau de l'étape chaine_miroir[i]=chaine_originale[k]. Pourriez-vous m'aider ?

    Voici mon code :

    #include <stdlib.h>
    #include <stdio.h>
    
    
    int len(char* chaine) //Fonction qui renvoi le nombre de caractère d'une chaine
    {
       unsigned int i,a = 0; // i --> variable pour itérer; a--> compte le nombre de caractère
    
       for (i = 0; chaine[i]; i++) // Pour i=0 dans chaine avec i +=1
        {
           a++;
        }
        return a;
    }
    
    int miror(int nb_car, char* chaine) //création de la chaine miroir
    {
        char mir[100]; //variable qui contiendra la chaine miroir
        unsigned int k = 0;
        while (nb_car > -1) //nb_car(actere) > -1 signifie qu'il reste encore des termes, donc on continue
        {
            mir[k]=chaine[nb_car]; //inversement des termes
            nb_car-- ; //On passe au terme précédent
            k++; //On passe au terme suivant
        }
        return mir;
    
    }
    
    int main()
    {
       char mot[100]; //Ne fonctionne pas avec 'char*'
       printf("Entrez un mot : ");
       scanf ("%s", mot); // On récupère la chaine
       printf("Nombre de caracteres : %i.\n", len(mot));
    
       printf("Voici : %s \n", miror(len(mot), mot));
    }
    



    • Partager sur Facebook
    • Partager sur Twitter
      23 février 2022 à 23:30:02

      Tu veux faire retourner une chaîne de caractère à ta fonction miroir et son prototype retourne un int ? ça n'est pas la même chose !

      Dans le code tu retournes bien l'adresse du tableau mir, mais le problème c'est que ce tableau est un tableau local à la fonction. Il n'existe que le temps de l'exécution de la fonction. Quand tu sors de la fonction il est détruit, il n'existe plus.

      • Partager sur Facebook
      • Partager sur Twitter
      ...
        23 février 2022 à 23:32:10

        Hello,

        Les warning ne sont pas là pour faire joli, il faut les régler:

        ab.c: In function 'miror':
        ab.c:26:12: warning: return makes integer from pointer without a cast [-Wint-conversion]
             return mir;
                    ^~~
        ab.c:26:12: warning: function returns address of local variable [-Wreturn-local-addr]
        

        Une fonction en C ne peux pas retourner un tableau local....

        Autre chose: tu parles de miroir[i] dans ta description, mais il ne se trouve pas dans ta fonction miroir. Et celle-ci va trop loin: elle devrait inverser les caractères jusqu'au milieu de la chaine, or toi tu les inverses tous, donc la chaine d'arrivée sera la même que la chaine de départ.

        -
        Edité par edgarjacobs 23 février 2022 à 23:32:22

        • Partager sur Facebook
        • Partager sur Twitter

        On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

          24 février 2022 à 0:23:56

          rouIoude a écrit:

          Tu veux faire retourner une chaîne de caractère à ta fonction miroir et son prototype retourne un int ? ça n'est pas la même chose !

          Dans le code tu retournes bien l'adresse du tableau mir, mais le problème c'est que ce tableau est un tableau local à la fonction. Il n'existe que le temps de l'exécution de la fonction. Quand tu sors de la fonction il est détruit, il n'existe plus.


          Je ne suis pas sûr de comprendre, il faudrait donc que déclare ma fonction Miror telle que : 

          char* miror(int nb_car, char* chaine)

           ?

          J'ai essayé et ça n'a rien changé.

          Aussi, j'ai essayé de déclaré mir comme une variable globale : 

          #include <stdlib.h>
          #include <stdio.h>
          
          char mir[100];
          

          et effectivement ça n'affiche plus "(null)", mais ça n'affiche toujours rien. 

          edgarjacobs a écrit:

          Hello,

          Les warning ne sont pas là pour faire joli, il faut les régler:

          ab.c: In function 'miror':
          ab.c:26:12: warning: return makes integer from pointer without a cast [-Wint-conversion]
               return mir;
                      ^~~
          ab.c:26:12: warning: function returns address of local variable [-Wreturn-local-addr]
          

          Une fonction en C ne peux pas retourner un tableau local....

          Autre chose: tu parles de miroir[i] dans ta description, mais il ne se trouve pas dans ta fonction miroir. Et celle-ci va trop loin: elle devrait inverser les caractères jusqu'au milieu de la chaine, or toi tu les inverses tous, donc la chaine d'arrivée sera la même que la chaine de départ.

          -
          Edité par edgarjacobs il y a environ 1 heure

          J'ai essayé de changer mir en variable globale mais ça n'affiche toujours pas le bon résultat (voir message au-dessus). 

          Je ne comrpends pas la seconde partie de ton message : miroir[i] avec i++, on passe à la lettre suivante de la chaine et pour chaine_originale[k] avec k--, on passe à la lettre suivante à chaque fois, je ne vois pas comment les deux chaines peuvent finir identique.... ? 



          -
          Edité par Sakisaac Jonathan 24 février 2022 à 0:29:21

          • Partager sur Facebook
          • Partager sur Twitter
            24 février 2022 à 0:42:01

            Sakisaac Jonathan a écrit:

            Je ne suis pas sûr de comprendre, il faudrait donc que déclare ma fonction Miror telle que : 

            char* miror(int nb_car, char* chaine)

            Oui, mais je suis étonné que tu ne comprennes pas ? Une chaîne de caractère, c'est quand même stocké dans un tableau de char ! Alors que viennent faire des entiers (int) ici ?

            Sakisaac Jonathan a écrit:

            Aussi, j'ai essayé de déclaré mir comme une variable globale ...

            et effectivement ça n'affiche plus "(null)", mais ça n'affiche toujours rien. 

            Alors, ça pourrait être une solution qui fonctionne, même si ce n'est pas la meilleure !

            Ça ne fonctionne pas, car ton algo n'est pas correcte :

            edgar t'as expliqué pourquoi ! 

            Quand tu écris : chaine[nb_car] , nb_car et la taille de la chaîne, n'oublies pas que le dernier caractère (visible) de la chaîne ce situe à l'indice (taille_de_la_chaine -1). Exemple pour la chaîne abcd :

            a b c d \0

            0 1 2 3 4



            -
            Edité par rouIoude 24 février 2022 à 0:44:31

            • Partager sur Facebook
            • Partager sur Twitter
            ...
              24 février 2022 à 0:53:34

              rouIoude a écrit:

              Sakisaac Jonathan a écrit:

              Je ne suis pas sûr de comprendre, il faudrait donc que déclare ma fonction Miror telle que : 

              char* miror(int nb_car, char* chaine)

              Oui, mais je suis étonné que tu ne comprennes pas ? Une chaîne de caractère, c'est quand même stocké dans un tableau de char ! Alors que viennent faire des entiers (int) ici ?

              Oui en effet c'est évident. En fait je pensais que toutes les fonctions devaient êtres déclarées en 'int' (comme main). Je me disais que c'était sûrement une convention. 

              rouIoude a écrit:

              Alors, ça pourrait être une solution qui fonctionne, même si ce n'est pas la meilleure !

              Ça ne fonctionne pas, car ton algo n'est pas correcte :

              edgar t'as expliqué pourquoi ! 

              Quand tu écris : chaine[nb_car] , nb_car et la taille de la chaîne, n'oublies pas que le dernier caractère (visible) de la chaîne ce situe à l'indice (taille_de_la_chaine -1). Exemple pour la chaîne abcd :

              a b c d \0

              0 1 2 3 4



              -
              Edité par rouIoude il y a moins de 30s

              Ah oui d'accord, merci beaucoup ! J'ai pris tout ça en compte et maintenant mon programme fonctionne !

              Un grand merci à vous deux ! 

              -
              Edité par Sakisaac Jonathan 24 février 2022 à 0:56:00

              • Partager sur Facebook
              • Partager sur Twitter
                24 février 2022 à 1:28:56

                Essaies de mettre le caractère 'x' (ou un autre) dans toutes les cases de mir "avant" d'appeler la fonction miror et tu verras ce que ça donne.

                Tu ne recopies pas le caractère de fin de chaîne '\0'. C'est une "chance" que mir soit initialisé à 0.

                Tu pourrais passer les deux chaînes en paramètre à ta fonction.
                Tu n'a pas besoin de passer la longueur. Pourquoi ne pas l'obtenir en appelant la fonction len() dans la fonction miror.

                -
                Edité par PierrotLeFou 24 février 2022 à 1:35:19

                • Partager sur Facebook
                • Partager sur Twitter

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

                  24 février 2022 à 12:25:35

                  J'ai un autre souci : j'aimerai que le programme me signale que le mot est un palindrome lorsque s'en est un.

                  En gros : Si chaine_originale = chaine miroir --> afficher : "Ce mot est un palindrome." 


                  J'ai déjà une fonction "miror" (fonctionnelle) qui me renvoi la chaine miroir et on recupère le mot (chaine_originale) dans la fonction main. Donc j'ai écris mon code ainsi dans la fonction main : Si chaine_originale == miroir(chaine_originale) --> afficher "Ce mot est un palindrome".

                  Le problème est que même si le mot est un palindrome (on entre "Anna" ou "Laval" par exemple), le programme me dit à chaque fois que ce n'en est pas un. 

                  Voici le code : 

                  #include <stdlib.h>
                  #include <stdio.h>
                  
                  char mir[100]; //si l'on met mir dans la fonction "miror", alors le programme affichera 'null'
                  int len_chaine; // On y enregistrera la longueur de la chaine
                  
                  unsigned int len(char* chaine) //Fonction qui renvoi le nombre de caractère d'une chaine
                  {
                     unsigned int i,a = 0;
                  
                     for (i = 0; chaine[i]; i++)
                      {
                         a++;
                      }
                      len_chaine = a;
                      return len_chaine;
                  }
                  
                  char* miror(char* chaine) //Fonction qui va créer la chaine miroir
                  {
                      unsigned int k = 0;
                      len_chaine--;       // le dernier terme est '\0' il ne nous interesse pas
                      while (len_chaine > -1) //Si len_chaine est supérieur à -1 c'est qu'il reste encore des lettres dans le mot
                      {
                          mir[k]=chaine[len_chaine]; //On ecrit la derniere lettre du mot a la premiere place dans la nouvelle chaine
                          len_chaine-- ; //On passe à la lettre d'avant...
                          k++; //...qu'on ecrira juste après la précédente
                      }
                      return mir;
                  
                  }
                  
                  int main()
                  {
                     char mot[100]; //Ne fonctionne pas avec 'char*'
                     printf("Entrez un mot : ");
                     scanf ("%s", mot); // On récupère la chaine
                     printf("Nombre de caracteres : %x.\n", len(mot));
                     printf("Miroir du mot : %s \n", miror(mot));
                  
                     if(mot == miror(mot)) //On regarde si c'est un palindrome
                         printf("%s est est un palindrome !\n", mot);
                      else
                          printf("%s n'est pas un palindrome.\n", mot);
                  
                  }


                  PierrotLeFou:

                  Merci, lorsque j'aurai fini mon programme je prendrai en compte tes remarques pour l'améliorer. Je n'utilise pas len() car j'essai de me débrouiller sans <string.h>. 

                  -
                  Edité par Sakisaac Jonathan 24 février 2022 à 12:28:49

                  • Partager sur Facebook
                  • Partager sur Twitter
                    24 février 2022 à 13:01:44

                    Alors pour comparer deux chaîne de caractères, on utilise la fonction strcmp! Toi tu compares l'adresse des chaînes !

                    Comme tu ne veux pas utiliser les fonctions de manipulation de chaîne de caractère (string.h) tu va devoir écrire ta fonction strcmp !

                    • Partager sur Facebook
                    • Partager sur Twitter
                    ...
                      24 février 2022 à 15:12:07

                      À partir d'un algorithme correct pour inverser une chaîne on pourrait facilement écrire celle qui teste si c'est un palindrome.
                      Au lieu de faire "j'échange le premier et le dernier", je ferais "je compare le premier et le dernier"., etc
                      • Partager sur Facebook
                      • Partager sur Twitter

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

                        25 février 2022 à 0:00:00

                        PierrotLeFou a écrit:

                        À partir d'un algorithme correct pour inverser une chaîne on pourrait facilement écrire celle qui teste si c'est un palindrome.
                        Au lieu de faire "j'échange le premier et le dernier", je ferais "je compare le premier et le dernier"., etc


                        Je ne sais pas comment fonctionne la fonction strcmp donc j'ai opté pour cette solution et ça a fonctionné. 

                        Merci beaucoup.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          25 février 2022 à 0:09:48

                          C'était donc un problème X Y ?

                          Tu demande comment inverser une chaîne de caractère, alors que tu veux savoir si c'est un palindrome !

                          Maintenant que tu as réussi, Il y aurait quand même quelques amélioration à apporter à ton code, C'est déjà de ne pas utiliser de variables globale.  

                          PS :

                          Sakisaac Jonathan a écrit:

                          Je ne sais pas comment fonctionne la fonction strcmp donc j'ai opté pour cette solution et ça a fonctionné. 

                          La comparaison de deux chaînes de caractère, devrait passé avant l'inversion de chaîne ou le palindrome !

                          -
                          Edité par rouIoude 25 février 2022 à 0:13:52

                          • Partager sur Facebook
                          • Partager sur Twitter
                          ...
                            25 février 2022 à 1:24:55

                            C'est vrai qu'on ne peut pas trouver nulle part la description de strcmp. :)

                            t

                            • Partager sur Facebook
                            • Partager sur Twitter

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

                              25 février 2022 à 9:06:06

                              PierrotLeFou a écrit:

                              C'est vrai qu'on ne peut pas trouver nulle part la description de strcmp. :)

                              Donc on peut la trouver partout :)

                              • Partager sur Facebook
                              • Partager sur Twitter

                              Le crayon la gomme et le papier sont les meilleurs outils du programmeur !

                                25 février 2022 à 11:41:24

                                La fonction 'strcmp' appartient à la bibliothèque <string.h>, donc Sakisaac Johathan ne pouvait pas s'en servir (relire la toute première phrase de son message).

                                -
                                Edité par robun 25 février 2022 à 11:42:09

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  25 février 2022 à 11:45:32

                                  On a bien comprit, c'est pour cela qu'il parle de la description, pas d'utiliser la fonction.

                                  Et c'est pour cela que je lui ai dit qu'il devra la réécrire. Mais pour cela il lui faut la description. 

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  ...
                                    25 février 2022 à 13:53:14

                                    strcmp page 98 "Le langage C" Kernigham & Ritchie édition en français avril 1986
                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    Le crayon la gomme et le papier sont les meilleurs outils du programmeur !

                                      25 février 2022 à 14:02:03

                                      joel76 a écrit:

                                      strcmp page 98 "Le langage C" Kernigham & Ritchie édition en français avril 1986

                                      Tu lui propose d'acheter le livre ? Tu sais maintenant quand tu veux une info rapidement, tu peux utiliser le réseau internet ! Il y a même des moteurs de recherche dessus, Google par exemple !

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      ...
                                        25 février 2022 à 16:32:03

                                        rouIoude a écrit:

                                        joel76 a écrit:

                                        strcmp page 98 "Le langage C" Kernigham & Ritchie édition en français avril 1986

                                        Tu lui propose d'acheter le livre ? Tu sais maintenant quand tu veux une info rapidement, tu peux utiliser le réseau internet ! Il y a même des moteurs de recherche dessus, Google par exemple !


                                        J'apprécie ton humour !

                                        Je ne me séparerai jamais d'un livre qui fût une référence.

                                        -
                                        Edité par joel76 25 février 2022 à 20:35:35

                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        Le crayon la gomme et le papier sont les meilleurs outils du programmeur !

                                          25 février 2022 à 19:02:55

                                          Bon, on réécrit toute la bibliothèque?
                                          On aura déjà strlen, strcmp. Tout va bien ...
                                          • Partager sur Facebook
                                          • Partager sur Twitter

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

                                            25 février 2022 à 20:36:53

                                            strcat dans mon livre, (copie exacte du code)
                                            strcat(s,t) /* concatenate t to end of s */
                                            char s[], t[]; /* s must be big enough */
                                            {
                                                int i, j;
                                                
                                                i = j = 0;
                                                while (s[i] != '\0') /* find end of s */
                                                    i++;
                                            
                                                while ((s[i++] = t[j++]) != '\0') /* copy t */
                                                    ;
                                            }

                                            Je ne sais pas si ce genre de code serait accepté maintenant, à l'époque c'était le must !

                                            A noter pas de return s !

                                            -
                                            Edité par joel76 25 février 2022 à 20:37:28

                                            • Partager sur Facebook
                                            • Partager sur Twitter

                                            Le crayon la gomme et le papier sont les meilleurs outils du programmeur !

                                              26 février 2022 à 0:35:34

                                              C'est pas tout jeune ! 

                                              La norme dit que strcat renvoie un pointeur sur la chaîne de destination !

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                              ...
                                                26 février 2022 à 2:10:39

                                                Est-ce plus moderne?
                                                -
                                                #include <stdio.h>
                                                char *strcat(char *dst, char *src) {
                                                    char *ptr = dst;
                                                    while(*dst) dst++;
                                                    while((*dst++ = *src++));
                                                    return ptr;
                                                }
                                                int main(void) {
                                                char dst[100] = "";
                                                    strcat(strcat(strcat(dst, "Albert"), " "), "Einstein");
                                                    puts(dst);
                                                }
                                                • Partager sur Facebook
                                                • Partager sur Twitter

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

                                                  26 février 2022 à 8:35:37

                                                  rouIoude a écrit:

                                                  C'est pas tout jeune ! 

                                                  La norme dit que strcat renvoie un pointeur sur la chaîne de destination !


                                                  Eh oui, ça a bien évolué !
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter

                                                  Le crayon la gomme et le papier sont les meilleurs outils du programmeur !

                                                    26 février 2022 à 15:42:16

                                                    Je ne sais pas de quand date ton livre mais dès les premières versions d'UNIX (ici V7 de janvier 1979) le code classique d'un strcat est :

                                                    /*
                                                     * Concatenate s2 on the end of s1.  S1's space must be large enough.
                                                     * Return s1.
                                                     */
                                                    
                                                    char *
                                                    strcat(s1, s2)
                                                    register char *s1, *s2;
                                                    {
                                                    	register char *os1;
                                                    
                                                    	os1 = s1;
                                                    	while (*s1++)
                                                    		;
                                                    	--s1;
                                                    	while (*s1++ = *s2++)
                                                    		;
                                                    	return(os1);
                                                    }

                                                    De nos jours l'approche est différente. Par exemple dans la gnu libc, un strcat est implémenté via strcpy+strlen, et strcpy est implémenté avec memcpy.
                                                    Au final toute la complexité des codes est condensée dans strlen et memcpy.

                                                     Une stratégie similaire est utilisée dans la Musl.

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      27 février 2022 à 0:22:04

                                                       "Le langage C" Kernigham & Ritchie édition en français avril 1986 chez Masson préface de G. Roucairol

                                                      Première édition : 1983.

                                                      C'est un livre conçu pour enseigner l'écriture de programmes en C.

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter

                                                      Le crayon la gomme et le papier sont les meilleurs outils du programmeur !

                                                        27 février 2022 à 1:28:47

                                                        Est-ce que strlen() a un truc magique pour avancer à la fin de la chaîne de destination?
                                                        Un bon compilateur optimiserait  while(*dst) dst++;  dans des registres.
                                                        Je ne sais pas comment memcpy() est implémenté en général.
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter

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

                                                          27 février 2022 à 8:04:48

                                                          Alors @Joel76,  je n'ai pas à ma disposition ton livre, mais dans le K&R 2ème édition original on trouve p45, juste avant ton exemple sans return :

                                                          K&R ont du rajouter cette ligne dans la seconde édition.

                                                          @Pierrot :

                                                          « Toute technologie suffisamment avancée est indiscernable de la magie. »
                                                          Troisième loi de Clarke.

                                                          La gnu libc caste le pointeur vers char de la chaîne en un pointeur vers un unsigned long (4 octets en 32bits, 8 en 64bits sous linux) et détermine si cet unsigned long pointé possède un octet valant 0. Bon juste avant de faire cela, il y a une portion qui checke la présence d'un '\0' le temps d'arriver à une adresse correctement alignée (tu as la code en lien). 

                                                          Ce n'est pas une «optimisation» du compilateur, mais une optimisation du codeur en considérant une plateforme.

                                                          La musl libc prend une approche similaire mais avec un code par défaut classique si on ne compile pas avec gcc :

                                                          #include <string.h>
                                                          #include <stdint.h>
                                                          #include <limits.h>
                                                          
                                                          #define ALIGN (sizeof(size_t))
                                                          #define ONES ((size_t)-1/UCHAR_MAX)
                                                          #define HIGHS (ONES * (UCHAR_MAX/2+1))
                                                          #define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
                                                          
                                                          size_t strlen(const char *s)
                                                          {
                                                          	const char *a = s;
                                                          #ifdef __GNUC__
                                                          	typedef size_t __attribute__((__may_alias__)) word;
                                                          	const word *w;
                                                          	for (; (uintptr_t)s % ALIGN; s++) if (!*s) return s-a;
                                                          	for (w = (const void *)s; !HASZERO(*w); w++);
                                                          	s = (const void *)w;
                                                          #endif
                                                          	for (; *s; s++);
                                                          	return s-a;
                                                          }

                                                          memcpy suit la même procédure = on commence par copier des gros morceau tant qu'on peut puis à la fin on copie en octet ce qui reste. Le code de musl est relativement  compréhensible et à nouveau possède un code par défaut classique si on ne compile pas avec gcc :

                                                          void *memcpy(void *restrict dest, const void *restrict src, size_t n)
                                                          {
                                                          	unsigned char *d = dest;
                                                          	const unsigned char *s = src;
                                                          
                                                          #ifdef __GNUC__
                                                          
                                                          #if __BYTE_ORDER == __LITTLE_ENDIAN
                                                          #define LS >>
                                                          #define RS <<
                                                          #else
                                                          #define LS <<
                                                          #define RS >>
                                                          #endif
                                                          
                                                          	typedef uint32_t __attribute__((__may_alias__)) u32;
                                                          	uint32_t w, x;
                                                          
                                                          	for (; (uintptr_t)s % 4 && n; n--) *d++ = *s++;
                                                          
                                                          	if ((uintptr_t)d % 4 == 0) {
                                                          		for (; n>=16; s+=16, d+=16, n-=16) {
                                                          			*(u32 *)(d+0) = *(u32 *)(s+0);
                                                          			*(u32 *)(d+4) = *(u32 *)(s+4);
                                                          			*(u32 *)(d+8) = *(u32 *)(s+8);
                                                          			*(u32 *)(d+12) = *(u32 *)(s+12);
                                                          		}
                                                          		if (n&8) {
                                                          			*(u32 *)(d+0) = *(u32 *)(s+0);
                                                          			*(u32 *)(d+4) = *(u32 *)(s+4);
                                                          			d += 8; s += 8;
                                                          		}
                                                          		if (n&4) {
                                                          			*(u32 *)(d+0) = *(u32 *)(s+0);
                                                          			d += 4; s += 4;
                                                          		}
                                                          		if (n&2) {
                                                          			*d++ = *s++; *d++ = *s++;
                                                          		}
                                                          		if (n&1) {
                                                          			*d = *s;
                                                          		}
                                                          		return dest;
                                                          	}
                                                          
                                                          	if (n >= 32) switch ((uintptr_t)d % 4) {
                                                          	case 1:
                                                          		w = *(u32 *)s;
                                                          		*d++ = *s++;
                                                          		*d++ = *s++;
                                                          		*d++ = *s++;
                                                          		n -= 3;
                                                          		for (; n>=17; s+=16, d+=16, n-=16) {
                                                          			x = *(u32 *)(s+1);
                                                          			*(u32 *)(d+0) = (w LS 24) | (x RS 8);
                                                          			w = *(u32 *)(s+5);
                                                          			*(u32 *)(d+4) = (x LS 24) | (w RS 8);
                                                          			x = *(u32 *)(s+9);
                                                          			*(u32 *)(d+8) = (w LS 24) | (x RS 8);
                                                          			w = *(u32 *)(s+13);
                                                          			*(u32 *)(d+12) = (x LS 24) | (w RS 8);
                                                          		}
                                                          		break;
                                                          	case 2:
                                                          		w = *(u32 *)s;
                                                          		*d++ = *s++;
                                                          		*d++ = *s++;
                                                          		n -= 2;
                                                          		for (; n>=18; s+=16, d+=16, n-=16) {
                                                          			x = *(u32 *)(s+2);
                                                          			*(u32 *)(d+0) = (w LS 16) | (x RS 16);
                                                          			w = *(u32 *)(s+6);
                                                          			*(u32 *)(d+4) = (x LS 16) | (w RS 16);
                                                          			x = *(u32 *)(s+10);
                                                          			*(u32 *)(d+8) = (w LS 16) | (x RS 16);
                                                          			w = *(u32 *)(s+14);
                                                          			*(u32 *)(d+12) = (x LS 16) | (w RS 16);
                                                          		}
                                                          		break;
                                                          	case 3:
                                                          		w = *(u32 *)s;
                                                          		*d++ = *s++;
                                                          		n -= 1;
                                                          		for (; n>=19; s+=16, d+=16, n-=16) {
                                                          			x = *(u32 *)(s+3);
                                                          			*(u32 *)(d+0) = (w LS 8) | (x RS 24);
                                                          			w = *(u32 *)(s+7);
                                                          			*(u32 *)(d+4) = (x LS 8) | (w RS 24);
                                                          			x = *(u32 *)(s+11);
                                                          			*(u32 *)(d+8) = (w LS 8) | (x RS 24);
                                                          			w = *(u32 *)(s+15);
                                                          			*(u32 *)(d+12) = (x LS 8) | (w RS 24);
                                                          		}
                                                          		break;
                                                          	}
                                                          	if (n&16) {
                                                          		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
                                                          		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
                                                          		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
                                                          		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
                                                          	}
                                                          	if (n&8) {
                                                          		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
                                                          		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
                                                          	}
                                                          	if (n&4) {
                                                          		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
                                                          	}
                                                          	if (n&2) {
                                                          		*d++ = *s++; *d++ = *s++;
                                                          	}
                                                          	if (n&1) {
                                                          		*d = *s;
                                                          	}
                                                          	return dest;
                                                          #endif
                                                          
                                                          	for (; n; n--) *d++ = *s++;
                                                          	return dest;
                                                          }




                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            27 février 2022 à 18:04:18

                                                            Mon K & R (en anglais) date de 1978, et page 44 on y trouve bien une version de strcat() qui est byte pour byte identique à celle donnée par @joel76. Je pense que c'est la première version du K & R, et (je viens de le remarquer) je l'ai payée 1750 FB (43.38 €). J'ai sans doute dû l'acheter en 1981.
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter

                                                            On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                                                              27 février 2022 à 18:12:57

                                                              Mon édition date plus de 88/89, post ANSI C. Le code y est bien identique, il n'y a qu'une ligne spécifiant que ce n'est pas la version de la libc, que l'exemple donné ne renvoyait pas de pointeur sur la chaîne concaténée.
                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              Inverser une chaine de caractère

                                                              × 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