Partage
  • Partager sur Facebook
  • Partager sur Twitter

inverser une chaîne de caractères

avec fonction Miroir()

    21 avril 2017 à 21:11:30

    salut tous le monde , alors pour cette fois je veux créer une fonction qui permet d'inverser une chaîne de caractères en utilisant deux fonctions.

    La premiére fonction est longueur_chaine() qui ça marche bien voici le code:

    int longueur_chaine_rec(char *s){
    	
    	if(*s == 0) return 0;
    	else
    	   return 1+longueur_chaine_rec(s+1);
    }

    et ensuite la 2éme fonction Miroir(), mais ici j'ai un probléme que je ne sais pas voici le code de deux versions de fct Miroir():

    Version 1:

    char* Miroir(char *ch){
    	char temp;
    	int i=0, n=longueur_chaine(ch)-1;
    	while(i<n/2){
    		
    		temp=*(ch+i);
    		*(ch+i)=*(ch+n-i);
    		*(ch+n-i)=temp;
    		i++;		
    	}
    	return ch;
    }

    Version 2:

    char* Miroir2(char *ch){
    	char temp;
    	int n=longueur_chaine(ch)-1,i;
    	
     for(i=0; i<n/2; i++){
        temp=*(ch+i);
        *(ch+i)=*(ch+n-i);
        *(ch+n-i)=temp;
     }	
    	return ch;
    }

    alors que mon programme complet est :

    #include <stdio.h>
    int longueur_chaine_rec(char *s){
    	
    	if(*s == 0) return 0;
    	else
    	   return 1+longueur_chaine_rec(s+1);
    }
    
    char* Miroir(char *ch){
    	char temp;
    	int i=0, n=longueur_chaine(ch)-1;
    	while(i<n/2){
    		
    		temp=*(ch+i);
    		*(ch+i)=*(ch+n-i);
    		*(ch+n-i)=temp;
    		i++;		
    	}
    	return ch;
    }
    
    char* Miroir2(char *ch){
    	char temp;
    	int n=longueur_chaine(ch)-1,i;
    	
     for(i=0; i<n/2; i++){
        temp=*(ch+i);
        *(ch+i)=*(ch+n-i);
        *(ch+n-i)=temp;
     }	
    	return ch;
    }
    
    main(){
    char *s="ANASS";
    
    printf("la taille est: %d\n",longueur_chaine(s));
    printf("le texte inverse est: %s\n",Miroir(s));
     
    }

    mais il ne marche pas il juste affiche le longueur de chaine mais pas l'inverse !! aidez-moi svp



    • Partager sur Facebook
    • Partager sur Twitter
    Hâmzà
      21 avril 2017 à 21:16:25

      Bonjour,

      utilise un debuger pour vérifier quels caractères sont échangés … fais un dessin pour bien comprendre lesquels tu devrais échanger et lesquels tu échanges réellement.

      • Partager sur Facebook
      • Partager sur Twitter
      First solve the problem. Then, write the code. ~ John Johnson
        21 avril 2017 à 21:59:51

        Hello, en ne lisant que quelques lignes...

        Ton main() n'est pas conforme.

        5.1.2.2.1  Program startup
        It shall  be  defined  with  a  return  type  of int and  with  no parameters:
        int main(void) { /*...*/ }
        or with two parameters (referred to here as argc and argv, though any names may be used, 
        as they are local to the function in which they are declared):
        int main(int argc, char *argv[]) { /*...*/ }

        Tu tentes de modifier une chaine littérale.

        6.4.5  String literals
        If the program attempts to modify such an array, the behavior is undefined.

        Sources tirées de la norme ISO/IEC 9899:201x.

        Après ces corrections, essaye à nouveau ton programme.

        -
        Edité par ASW_ 21 avril 2017 à 22:05:10

        • Partager sur Facebook
        • Partager sur Twitter
          25 avril 2019 à 19:47:09

          char* miroir(char *s)
          {
          char *aux;
          int i,n=strlen(s)-1;
          for(i=0;i<=n;i++)
            *(aux+i)=*(s+(n-i));
          return aux;
          }
          • Partager sur Facebook
          • Partager sur Twitter
            25 avril 2019 à 22:38:20

            1) Tu remonte un vieux sujet !

            2) Tu ne postes pas ton code correctement à l'aide du bouton code </> !

            3) Tu as oublier de poser ta question !

            4) Ton code ne fonctionne pas ! 

            • Partager sur Facebook
            • Partager sur Twitter
              30 avril 2019 à 1:30:04

              c'est ma premier intervention dans ce site je suit désolé mais mon code est bien exécuté  !

              char* miroir(char *s)
              {
              char *aux;
              int i,n=strlen(s)-1;
              for(i=0;i<=n;i++)
                *(aux+i)=*(s+(n-i));
              return aux;
              }
              



              -
              Edité par YassinBJ 30 avril 2019 à 1:31:06

              • Partager sur Facebook
              • Partager sur Twitter
                30 avril 2019 à 10:52:34

                Non ton code ne marche pas.

                Tu déclares un pointeur aux qui pointe n'importe où et tu le déréférence pour lui assigner une valeur. je ne vois pas comment ça peut fonctionner a part avec de la (mal)chance ?

                • Partager sur Facebook
                • Partager sur Twitter
                  30 avril 2019 à 19:21:11

                  Ceci est un code possible

                  char *reverse( const char *s_in )
                  {
                      char *s_out = NULL;
                      if ( s_in )
                      {
                          size_t sz = strlen( s_in );
                          if ( ( s_out = malloc( ++sz*sizeof( *s_out ) ) ) )
                          {
                              for( size_t i=0 ; i<sz ; i++ )
                                  s_out[i] = s_in[sz-2-i];
                  
                              s_out[sz-1] = '\0';
                          }
                      }
                      return s_out;
                  }

                  Nullement besoin exécuter ton code pour savoir qu'il est incorrect à bien des égards.
                  - Tu ne testes pas ton pointeur d'entrée
                  - Tu n'initialises pas ton pointeur de sortie
                  - Tu n'alloues pas ton pointeur de sortie
                  - Tu utilises de mauvais types pour déclarer tes variables, char* au lieu de const char*, ta chaîne d'entrée n'est jamais modifiée. Idem pour ta boucle, il faudrait plutôt utiliser un size_t qu'un int.
                  - Ton algorithme est faux et oublie le dernier caractère de ta chaîne plus le caractère \0 qui est le caractère de fin de chaine.

                  Ça fait beaucoup pour une fonction simple.
                  En tous cas, ton compilateur, quel qu’il soit est robuste :magicien:

                  -
                  Edité par aneonymous 30 avril 2019 à 19:32:55

                  • Partager sur Facebook
                  • Partager sur Twitter
                    30 avril 2019 à 21:58:28

                    Bonjour

                    aneonymous a écrit:

                    Ceci est un code possible

                    Il y a un bug sur reverse("").

                    • Partager sur Facebook
                    • Partager sur Twitter
                      30 avril 2019 à 22:04:37

                      pas faux... Qui corrige ?
                      • Partager sur Facebook
                      • Partager sur Twitter
                        1 mai 2019 à 19:56:16

                        Ce n'est pas parceque ça fonctionne chez toi que c'est le cas partout.

                        Par exemple, chez moi ça crash. Logique puisque comme on te l'a expliqué il y a plusieurs problèmes, le principal étant que tu n'initialises pas ton pointeur aux (qui pointe donc n'importe où) et que tu le déréférence derrière.
                        Si cela fonctionne chez toi c'est uniquement de la (mal)CHANCE !

                        • Partager sur Facebook
                        • Partager sur Twitter
                          6 mai 2019 à 1:53:48

                          chaque fois j'ai affecté un pointeur à un autre pourquoi je le initialise le deuxième !!

                          on suppose que tu as raison je doit initialiser NULL pour ton satisfait ?

                          • Partager sur Facebook
                          • Partager sur Twitter
                            6 mai 2019 à 10:51:00

                            Bonjour YassinBJ,

                              L'initialisation des pointeurs (de tout type de variable en fait) est une garantie; Elle te permet de t'assurer qu'à n'importe quel moment de l'éxécution du programme l'état (sa valeur) ta variable (e.g pointeurs) soit défini. Un pointeur contient une adresse, lors de la création d'un pointeur l'adresse vers laquel pointe ton pointeur ne peut pas être connue à l'avance.

                              Lorsque tu initialise ton pointeur à NULL (qui équivaut à 0x00000000 pour une adresse en 32bits), tu peux à l'avance connaître l'état de ta variable avant sa modification. Connaître l'état de ta variable permet de garantir la conformité de tes données.

                            Aller un petit exemple:

                            int  main(int argc, char *argv[])
                            {
                              char *s; // Non initialisé !!!
                            
                              if (argc > 2) // On vérifi que la longueur d'argv
                                 s = argv[1];
                            
                              //Ici je veux m'assurer que ma variable est conforme à 
                              //ce que j'attends en paramètre du programme 
                              //(argv[1]).
                              // Comment ferais-tu pour t'assurer que 's' contient
                              //la valeur voulue ?
                              //Réponse: tu ne peux pas. Si le programme est lancé
                              //sans arguments tu n'as acutellement aucun moyen de
                              //vérifié que 's' contient les informations voulues.
                              return (0);
                            }
                            
                            
                            

                            Alors qu'en initialisant 's' à NULL tu peux vérifier de cette manière :

                            int  main(int argc, char *argv[])
                            {
                              char *s = NULL;
                            
                              if (argc > 2)
                                 s = argv[1];
                            
                              if (s != NULL)
                              {
                               //Ici ma donnée est conforme, ou du moins son état a 
                               //bien été modifié, dans le cas où le programme n'est 
                               //pas lancé avec des paramètres je suis certain que 
                               //ma partie de code ayant besoin de l'information ne 
                               //sera pas éxécutée.
                              }
                              return (0);
                            }

                            Je sais qu'il y a toujours un moyen de vérifier l'intégrité de ses données autrement qu'en initialisant ses variables, mais cela requiert beaucoup de code pour le vérifier.

                            Remarque:
                              Je te trouve plutôt agressif sur tes réponses. Sâche que personne n'est payé pour t'apprendre les "bonnes manières" de codage ici. Je vois très bien que tu ne maîtrise pas le français c'est pourquoi j'émets un doute sur tes intentions d'être agressif.

                            En espèrant t'avoir éclairé sur le fait qu'il faut TOUJOURS initialisé ses variables.

                            Nicolas;

                            -
                            Edité par Nicolas Cathala 6 mai 2019 à 10:54:06

                            • Partager sur Facebook
                            • Partager sur Twitter
                              6 mai 2019 à 10:52:03

                              J'ai rien compris a ta phrase ...

                              Ton pointeur aux n'est PAS initialisé. Tu l'as seulement déclaré et ensuite tu essayes de stocker quelque chose dedans.
                              Si ça fonctionne c'est seulement de la chance. Si tu initialises aux a nullptr tu verras que ça crash.

                              Et pour info, tu n'as rien a faire pour me satisfaire, on te dit seulement ce qu'il en est. Tu ne veux pas nous croire/écouter ? Libre à toi, mais le jour ou ton programme crashera parceque tu n'as pas initialisé un pointeur, tu comprendras.

                              -
                              Edité par ironwolf151 6 mai 2019 à 10:55:21

                              • Partager sur Facebook
                              • Partager sur Twitter
                                6 mai 2019 à 18:58:36

                                Toujours une agressivité chez certains... d'accord ce code ne marche pas il est pourri mais ce n'est pas une raison pour s’engueuler! bref je pense que ce genre de topique est toxique pour la communauté, car est-ce que hamzasaber3 a trouvé la réponse à sa question? ce débat ne mene absolument nulle (NULL) part.

                                -
                                Edité par Scover 6 mai 2019 à 18:59:48

                                • Partager sur Facebook
                                • Partager sur Twitter

                                L'instant présent est celui où la mort n'a jamais été aussi proche. Ambiance!

                                  6 mai 2019 à 20:35:31

                                  Scover a écrit:

                                  car est-ce que hamzasaber3 a trouvé la réponse à sa question? 

                                  J'espère pour lui, car depuis le 21 avril 2017, ce qui fait deux ans, s'il n'a pas trouvé, il a surement changé de métier !

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    7 mai 2019 à 2:18:57

                                    au contraire je ne suit pas agressif peut être j'ai mal exprimé a cause de ma langage  

                                    je suit désolé !
                                    qui peut corriger ce code ?

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      7 mai 2019 à 9:54:50

                                      Bonjour YassinBJ,

                                        Biensur ! Tu as plusieurs façons de faire qui s'offre à toi, mais tu devras d'abord te poser quelques questions :

                                      - Est-ce que je veux effectuer le renversement de la chaîne sans allocation mémoire ?

                                      - Est-ce que ma chaîne est en READ_ONLY (signifiant qu'elle ne peut être modifié) ?

                                      - Est-ce que je veux que ma fonction détecte les palindromes (aucune action à effectuer sur un palindrome -> "LOL" donnera ..... "LOL") ?

                                      - Etc...

                                      Voici deux exemple de code :

                                      Cette première fonction fait appel à l'allocation mémoire, et est donc "coûteuse" mais tu as la possibilité de passer en paramètre une chaîne dite 'const' (C.A.D non modifiable). Cette fonction return une nouvelle chaîne allouée qu'il faudra 'free()' (cf. allocation mémoire).

                                      char            *reverse_with_alloc(const char *str)
                                      {
                                          char        *result = NULL;
                                          size_t      len = strlen(str) - 1;
                                          size_t      i = 0;
                                      
                                          //Str est NULL rien à faire ici !
                                          if (str == NULL)
                                              return (NULL);
                                      
                                          //Allocation de result de la taille de str + 1 (pour le '\0')
                                          //Si malloc retourne NULL (rare) l'allocation ne sera pas faite
                                          //on retourne donc NULL pour signaler une erreur.
                                      
                                          if ((result = malloc(sizeof(*result) * len + 1)) == NULL)
                                              return (NULL);
                                          
                                          //On boucle sur la longueur de la chaîne 'str', en décalant 'len'
                                          //par rapport à 'i' ce qui nous permet de récupérer les caractères
                                          //de la fin vers le début de la chaîne.
                                      
                                          for (; i < len; i++)
                                          {
                                              result[i] = str[len - i];
                                          }
                                          //On oublie pas le caractère signalant la fin d'une chaîne '\0'
                                      
                                          result[i] = '\0';
                                          return (result);
                                      }

                                      Deuxieme fonction, beaucoup moins "coûteuse" car elle ne fait pas d'allocation mémoire; Elle ne return rien, elle modifie la chaîne passée en paramètre et la renverse. Cependant cette fonction ne peut pas s'appliquer sur une chaîne non modifiable puisque .... on modifie justement la chaîne passée en paramètre.

                                      void            reverse(char *str)
                                      {
                                          size_t      i = 0;
                                          size_t      len = strlen(str) - 1;
                                          char        tmp = 0;
                                      
                                          //Str est NULL rien à faire ici !
                                          if (str == NULL)
                                              return ;
                                          
                                          //On échange les caractères de fin et de début (obliger de passer par une temporaire 'tmp').
                                          
                                          while (i < len)
                                          {
                                              tmp = str[i];
                                              str[i] = str[len];
                                              str[len] = tmp;
                                              i++;
                                              len --;
                                          }
                                      }

                                      Essaye de voir avec ces deux exemples se qu'il faudrait changer dans ta fonction pour qu'elle remplisse sa tâche.

                                      Nicolas;



                                      -
                                      Edité par Nicolas Cathala 7 mai 2019 à 9:58:50

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        7 mai 2019 à 11:50:16

                                        Nicolas Cathala a écrit:

                                        Deuxieme fonction, beaucoup moins "coûteuse" car elle ne fait pas d'allocation mémoire; Elle ne return rien, elle modifie la chaîne passée en paramètre et la renverse. Cependant cette fonction ne peut pas s'appliquer sur une chaîne non modifiable puisque .... on modifie justement la chaîne passée en paramètre.

                                        void reverse(char *str)
                                        {
                                            size_t      i = 0;
                                            size_t      len = strlen(str) - 1;
                                            char        tmp = 0;
                                        
                                            //Str est NULL rien à faire ici !
                                            if (str == NULL)
                                                return ;
                                            
                                            //On échange les caractères de fin et de début (obliger de passer par une temporaire 'tmp').
                                            
                                            while (i < len)
                                            {
                                                tmp = str[i];
                                                str[i] = str[len];
                                                str[len] = tmp;
                                                i++;
                                                len --;
                                            }
                                        }

                                        Essaye de voir avec ces deux exemples se qu'il faudrait changer dans ta fonction pour qu'elle remplisse sa tâche.

                                        Nicolas;

                                        C'est pas que ce code ne marche pas, mais il y a des petites choses à arranger

                                        • faire strlen() sur un pointeur NULL, est-ce bien raisonnable ? Tester avant....
                                        • quand une variable s'appelle len, c'est normalement qu'elle représente la longueur d'une chaine. Ce n'est pas le cas ici (quand on fait len--, c'est la longueur de quoi qui change ?). Ecrire "len", c'est mettre le lecteur sur une mauvaise voie.
                                        • quand on utilise une variable auxiliaire pour, par exemple, échanger le contenu deux variables, on la déclare AU PLUS PRES de l'endroit où on fait ça.  Au passage, ça évite de faire une initialisation bidon.
                                        void reverse(char *string)
                                        {
                                            if (string == NULL) {
                                                return;
                                            }
                                            ssize_t  left = 0,                      // edit, bug signalé
                                                     right = strlen(string) - 1;    // par marc mongenet
                                             
                                            while (left < right)
                                            {
                                                char tmp      = string[left];
                                                string[left]  = string[right];
                                                string[right] = tmp;
                                                left++;
                                                right--;
                                            }
                                        }

                                        Mieux, avec une boucle for

                                        for (ssize_t left=0, right=strlen(string)-1;  left < right; left++, right--) {
                                           char tmp = ...:
                                           ...
                                        }
                                         



                                        -
                                        Edité par michelbillaud 7 mai 2019 à 16:32:44

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          7 mai 2019 à 14:19:14

                                          Bonjour michelbillaud,

                                          En effet, il devrait y avoir une partie dans les règles du forum interdisant de donner des conseils lors de la pause au travail, le cerveau n'y est plus !

                                          Merci pour cette correction !

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            7 mai 2019 à 15:00:40

                                            Bonjour Michel et Nicolas,

                                            Il me semble que vos codes contiennent de graves erreurs. Je pense surtout au dépassement de tampon en cas de traitement de chaine vide. Sinon, le reverse_with_alloc n'alloue pas assez de RAM, et copie incomplétement.

                                            -
                                            Edité par Marc Mongenet 7 mai 2019 à 15:01:06

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              7 mai 2019 à 16:29:39

                                              Effectivement,

                                              • right devrait être un ssize_t. puisqu'il peut prendre la valeur - 1
                                              • Et pour pas être emmerdé par la comparaison signé/non signé, left aussi.

                                              Corrigé dans le code plus haut. Merci de l'avoir signalé.

                                              -
                                              Edité par michelbillaud 7 mai 2019 à 16:31:53

                                              • Partager sur Facebook
                                              • Partager sur Twitter

                                              inverser une chaîne de caractères

                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                              • Editeur
                                              • Markdown