Partage
  • Partager sur Facebook
  • Partager sur Twitter

[C] chaines de caractères

coder la fonction de recherche

    1 avril 2006 à 5:06:35

    salut à tous!! :D
    encore une fois je post ici parce que mon code ne marche pas!!
    en effet, j'ai fait la fonction de recherche du premier caractere qui marche très bien mais dès que je met celle de recherche du dernier caractère, rien ne va plus!!
    je vous mais mon code en espèrant que vous puissiez m'aider...

    main.c
    int main(int argc, char *argv[])
    {
        char chaine1[100] = "Salut ", chaine2[] = "Erwan", chaine3[] = "Texte de test", copie[100] = {0}, *suiteChaine = NULL, *debutChaine = NULL;
        long longueur = 0;
       
        longueur = longueurChaine(chaine1);
        copieChaine(chaine1, copie);
        suiteChaine = recherche_premier(chaine3, 'd');
        debutChaine = recherche_dernier(chaine3, 'e');
           
        printf("La chaine \"%s\" fait %ld caracteres de long\n\n", chaine1, longueur);
        printf("chaine vaut : %s\n", chaine1);
        printf("copie vaut : %s\n\n", copie);
       
        concatenation(chaine2, chaine1);
       
        printf("chaine1 vaut: %s\n", chaine1);
        printf("chaine2 vaut toujours: %s\n\n", chaine2);
       
        if (comparaison(chaine2, chaine3) == 0)
        {
           printf("Les chaines \"%s\" et \"%s\" sont identiques\n\n", chaine2, chaine3);
        }
        else
        {
            printf("Les chaines \"%s\" et \"%s\" sont differentes\n\n", chaine2, chaine3);
        }
       
        if (suiteChaine != NULL)
        {
            printf("Voici la fin de la chaine a partir du premier d : %s\n\n", suiteChaine);
        }
       
        if (debutChaine != NULL)
        {
            printf("Voici le debut de la chaine jusqu'au dernier e : %s", debutChaine);
        }
       
        printf("\n");
        system("PAUSE");
        return 0;
    }


    chaines.c
    long longueurChaine(const char* chaine)
    {
        long nombreDeCaracteres = 0;
        char caractereActuel = 0;

        do
        {
            caractereActuel = chaine[nombreDeCaracteres];
            nombreDeCaracteres++;
        }
        while(caractereActuel != '\0'); /* On boucle tant qu'on n'est pas arrivé à l'\0*/

        nombreDeCaracteres--; /* On retire 1 caractère de long pour ne pas compter l'\0*/

        return nombreDeCaracteres;
    }

    char* recherche_premier(const char* chaine, int caractereAchercher)
    {
          long nombreDeCaracteres = 0, position = 0;
          char caractereActuel = 0, chaineFin[200] = {0};

          do
          {
               caractereActuel = chaine[nombreDeCaracteres];
               nombreDeCaracteres++;
          }
          while(caractereActuel != caractereAchercher);
         
          nombreDeCaracteres--;
         
          do
          {
               chaineFin[position] = chaine[nombreDeCaracteres];
               nombreDeCaracteres++;
               position++;
          }
          while(chaine[nombreDeCaracteres] != '\0');
         
          return chaineFin;
    }

    char* recherche_dernier(const char* chaine, int caractereAchercher)
    {
          long nombreDeCaracteres = 0, position = 0;
          char caractereActuel = 0, chaineDebut[200] = {0};
         
          nombreDeCaracteres = longueurChaine(chaine);
          position = nombreDeCaracteres;
         
          do
          {
               caractereActuel = chaine[nombreDeCaracteres];
               nombreDeCaracteres--;
          }
          while(caractereActuel != caractereAchercher); /* On boucle tant qu'on n'est pas arrivé à l'\0*/
         
          do
          {
               chaineDebut[position] = chaine[nombreDeCaracteres];
               nombreDeCaracteres--;
               position--;
          }
          while(chaine[nombreDeCaracteres] != '\0');
         
          return chaineDebut;
    }


    chaines.h
    long longueurChaine(const char* chaine);
    char* recherche_premier(const char* chaine, int caractereAchercher);
    char* recherche_dernier(const char* chaine, int caractereAchercher);


    merci d'avance!!

    ps: pour ne pas trop encombrer je n'ai mis que les fonctions qui m'intéressent à ce moment précis!
    • Partager sur Facebook
    • Partager sur Twitter
      1 avril 2006 à 8:32:00

      Il suffit d'inverser la fonction de recherche de la première occurence : lis la chaine de la fin jusqu'au début au lieu du contraire.

      Pour le faire ressortir, version avec pointeurs :

      char* chr_p(char *s, char c)
      {
          while(*s++ != c)
              ;
          return --s;
      }     

      char* chr_d(char *s, char c)
      {
          s = s + strlen(s);
          while(*s-- != c)
              ;
          return ++s;
      }


      On voit bien qu'on réalise 2 fois les deux mêmes actions, sauf que dans le deuxième cas on parcourt la chaine à l'envers.

      ++.
      • Partager sur Facebook
      • Partager sur Twitter
        1 avril 2006 à 14:24:47

        excuse moi mais j'ai quelques problèmes à te suivre!! oO (en clair j'ai rien compris presque!!)
        • Partager sur Facebook
        • Partager sur Twitter
          1 avril 2006 à 20:20:03

          Qu'est-ce que t'as pas compris ?

          Ce n'est qu'une application des pointeurs.

          Le truc était de dire qu'il fallait inverser le sens de la fonction, ce que tu as eu l'air de faire, mais mal.

          Voici donc une version sans pointeurs (enfin presque : s + ++i est un calcul d'adresse obligatoire), ie celle que je voulais te faire trouver :

          char* recherche_dernier(char *s, char c)
          {
              int i = strlen(s);
             
              while(s[i--] != c)
                  ;   

              return s + ++i;
          }


          ++.
          • Partager sur Facebook
          • Partager sur Twitter
            2 avril 2006 à 14:44:25

            je connais pas le ++i!!

            et pour coder cette fonction il faut utiliser un int sur c et non un char!!

            aussi je ne sais pas ce qu'est un calcul d'adresse obligatoire!!
            • Partager sur Facebook
            • Partager sur Twitter
              2 avril 2006 à 15:02:31

              Yop.

              Pour le coup du int au lieu du char bah les deux conviennent, le char est un petit entier avant tout donc en gros c'est du pareil au même. :p

              Ensuite ce que je voulais dire par 'calcul d'adresse obligatoire' était : 'calcul d'adresse obligatoire pour coder cette fonction', puisque strchr est censé retourner un pointeur sur le caractère trouvé. L'usage des pointeurs est donc nécessaire. ;)

              Quant au ++i, i est incrémenté avant de faire l'opération, et non après comme l'aurait fait i++.

              return s + ++i;

              ... c'est donc un condensé de

              i++;
              return s + i;


              Récapitulons donc :
              • On donne pour valeur à i la longueur de la chaine
              • On boucle en décrémentant i jusqu'à trouver le caractère recherché
              • s + i ferait pointer s sur le caractère juste avant le bon, donc on incrémente, ça nous donne : s + ++i


              Voilà j'espère que c'est plus clair. :)

              ++.
              • Partager sur Facebook
              • Partager sur Twitter
                2 avril 2006 à 15:14:44

                Citation : mleg

                Quant au ++i, i est incrémenté avant de faire l'opération, et non après comme l'aurait fait i++.


                Terrain glissant.

                Citation : mleg


                return s + ++i;



                Je dirais qu'il n'y a pas de point de séquencement et que par conséquent, le comportement est indéfini.
                C'est une zone sombre du C que personnellement j'ai décidé d'éviter totalement au profit d'une écriture claire pour tout le monde :

                Citation : mleg


                i++;
                return s + i;



                Là, au moins il n'y a pas de discussion possible. Mais ceci est encore plus simple :
                return s + i + 1;

                • Partager sur Facebook
                • Partager sur Twitter
                Music only !
                  2 avril 2006 à 16:08:56

                  ok merci pour vos réponses!!
                  maintenant je comprends mieux!!
                  mais j'ai un autre problème avec une autre fonction: celle de recherche d'une chaine dans une autre!
                  quand je lance le programme, il coupe a cause d'une erreur!
                  je vous met mon code au cas où vous pourriez m'aider!!

                  char* recherche_chaine(const char* chaine, const char* chaineARechercher)
                  {
                        int i = 0, z = 0, y = 0, a = longueurChaine(chaine), b = longueurChaine(chaineARechercher);
                       
                        while(i != a-b)
                        {
                                z = i;
                               
                                while(y != b-1)
                                {
                                        while(chaine[z++] != chaineARechercher[y++]);
                                }
                               
                                if(z = i)
                                {
                                       return chaineARechercher;
                                }
                                             
                                i++;
                        }
                  }
                  • Partager sur Facebook
                  • Partager sur Twitter
                    2 avril 2006 à 17:15:51

                    if(z = i)
                        /* ... */


                    -> if (z == i)
                    • Partager sur Facebook
                    • Partager sur Twitter
                      2 avril 2006 à 17:32:30

                      pourquoi retourner "chaineARechercher" et ne pas simplement renvoyer l'index du 1er caractère de "chaineARechercher" dans "chaine" ?
                      • Partager sur Facebook
                      • Partager sur Twitter
                        2 avril 2006 à 18:28:35

                        Si ça peut t'aider, voici une version avec pointeur encore, essaye de la réécrire en indexant les chaines cette fois. ;)

                        /* chr_s : cherche t dans s ; version avec pointeurs. */
                        int chr_s(char *s, char *t)
                        {
                            size_t size;
                            int bon;
                            char *temp;
                           
                            size = 0;   
                            temp = t;
                            while(*temp++)
                                size++;
                               
                            size++;
                           
                            bon = 0;
                            while(*s++) {
                                if (*s == *t) {
                                        bon++;
                                        t++;
                                }       
                            }
                           
                            if (bon == size) {
                                bon--;
                                return bon;
                            }   
                            else return 0;
                        }


                        ++ et bonne chance.

                        [e:] Code défectueux édité ;) [\e]
                        • Partager sur Facebook
                        • Partager sur Twitter
                          2 avril 2006 à 18:47:45

                          Citation : minirop

                          pourquoi retourner "chaineARechercher" et ne pas simplement renvoyer l'index du 1er caractère de "chaineARechercher" dans "chaine" ?


                          Bonne remarque. Je suppose que c'est parce qu'on cherche à reproduire la comportement de strchr() et strrchr() qui retourne l'adresse de l'élément trouvé ou NULL si il est inconnu.

                          On ne peut pas faire ça avec un entier non signé de type size_t. Si on utilise int ou long, on risque de perdre la moitié de la plage possible d'un size_t. Ou alors il faudrait définir un mécanisme tordu qui dit : si la valeur est 0, on a rien trouvé, sinon, l'index est à n -1, avec les innombrables risques d'erreur possible.

                          Nota : A partir de l'adresse, il est simple de calculer l'index. Quelque soit le type (encore une propriété de l'arithmétique des pointeurs), c'est toujours l'adresse de l'élement - l'adresse du premier élément. Le résultat est de type ptrdiff_t. Si il est >=0, il peut être convertit en size_t, qui est le bon type pour un index.

                          Concevoir une interface de fonction à la fois performante, fiable et facile d'utilisation n'est pas chose facile. La plupart des fonctions standard du C sont réussies (plus ou moins faciles d'emploi), certaines auraient pu être améliorées (mais le C a un lourd passé), d'autres (très peu) sont des bugs.
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Music only !
                            2 avril 2006 à 20:38:58

                            oula moi je suis largué!!
                            je vais essayer avec ce que vous m'avez donné mais je garantis pas parce que je comprend pas tout!!
                            • Partager sur Facebook
                            • Partager sur Twitter
                              5 avril 2006 à 22:46:59

                              bon j'ai cherché à comprendre le code de mleg mais je comprends vraiment pas... :(

                              pourriez vous m'éclairer??
                              • Partager sur Facebook
                              • Partager sur Twitter
                                6 avril 2006 à 20:05:04

                                En fait j'incrémente la variable bon si la lettre recherchée correspond à la lettre effective de la chaîne où l'on cherche, puis je compare bon à size, qui est la longueur de la chaîne à rechercher : si l'un égal l'autre, c'est que la chaîne a été trouvée. ;)

                                Au pire MP moi je te l'enverrai avec des commentaires partout. :p
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  11 avril 2006 à 20:38:59

                                  bien j'avance dans le cours et je fais donc la fonction pour écrire dans une chaine!!
                                  malheureusement ça marche pas (à vrai dire je m'en doutais!!)...

                                  alors si vous pouvez m'aider merci beaucoup!!

                                  voici le code:
                                  void ecritChaine(char* chaine, const char* chaineAInserer, ...)
                                  {
                                       long i = 0, j = 0, t = 0;
                                       
                                       while (chaineAInserer[i] != '\0')
                                       {
                                             if (*... != NULL)
                                             {
                                                if (chaineAInserer[i] == '%')
                                                {
                                                   i++;
                                               
                                                   if (chaineAInserer[i] == 's')
                                                   {
                                                   
                                                      i--;
                                                                                       
                                                      while (...[j] != '\0')
                                                      {
                                                         chainAInserer[i] = ...[j];
                                                         i++;
                                                         j++;
                                                      }
                                                   }
                                                   else if (chaineAInserer[i] == 'l')
                                                   {
                                                        i++;
                                                     
                                                        if (chaineAInserer[i] == 'd')
                                                        {
                                                           i--;
                                                           i--;
                                                                                   
                                                           while (...[j] != '\0')
                                                           {
                                                                 chainAInserer[i] = ...[j];
                                                                 i++;
                                                                 j++;
                                                           }
                                                        }
                                                   }
                                                }
                                             }
                                       }
                                       
                                       i = 0;

                                       while (chaineAInserer[i] != '\0')
                                       {
                                             chaine[i] = chaineAInserer[i];
                                             i++;
                                       }
                                  }
                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  [C] chaines de caractères

                                  × 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