Partage
  • Partager sur Facebook
  • Partager sur Twitter

Fonction concaténer

faite "maison"

Sujet résolu
    12 janvier 2006 à 19:03:05

    Bonsoir,

    pour les cours, je dois créer une fonction (sans utiliser sprintf()) qui réalise une concaténation de deux chaines de caractère.

    Voilà tout d'abord mon code:

    void concat(char *chaine1, char *chaine2, char *tabc)
    {
        int i=0;
        int j=0;
            while(chaine1[i]!='\0')
            {
                    tabc[i]=chaine1[i];
                    i++;
            }
            i++;
            while(chaine2[j]!='\0')
            {
            tabc[i]=chaine2[j];
                    i++;
                    j++;
            }
       tabc[i+1]='\0';
    }


    Et voilà le résultat:
    http://img456.imageshack.us/img456/5734/bug8za.jpg
    Donc le premier mot s'affiche bien (c'est "t") cependant vous pouvez voir qu'il y a un gros bug au niveau du deuxième. :s

    Pouvez-vous m'aider s'il vous plaît ?
    Merci.
    • Partager sur Facebook
    • Partager sur Twitter
      12 janvier 2006 à 19:12:03

      Enlève le i++ situé entre les deux while.
      • Partager sur Facebook
      • Partager sur Twitter
        12 janvier 2006 à 19:14:07

        :D

        si la concaténation étais aussi simple, ce serais plus du C.
        ça bug car tu n'a pas alloué la mémoire pour la chaine de caractères (cf fonctions malloc et free).
        C'est pour ça qu'on dit depuis toujours qu'il ne faut pas que vous touchiez aux chaines de caractères, car le C n'est pas trivial la dessus.
        • Partager sur Facebook
        • Partager sur Twitter
          12 janvier 2006 à 19:16:45

          drexil > sa fonction peut très bien marcher, il s'agit juste de gêrer l'allocation de la mémoire de tabc par ailleurs, en dehors de la fonction. On n'a pas à se préoccuper de ça ici, le char *tabc en argument suffit.
          • Partager sur Facebook
          • Partager sur Twitter
            12 janvier 2006 à 19:25:01

            Citation : drexil


            C'est pour ça qu'on dit depuis toujours qu'il ne faut pas que vous touchiez aux chaines de caractères, car le C n'est pas trivial la dessus.


            Si mon prof disait pareil, ça m'arrangerait mais ce n'est pas le cas. :-°

            @ Elentar: le i++, je l'avais rajouté pour voir ce que ça donné avec. Sans, ça fait pareil.^^;

            Citation : drexil

            (cf fonctions malloc et free)


            J'connais pas ces fonctions. ^^;

            • Partager sur Facebook
            • Partager sur Twitter
              12 janvier 2006 à 19:30:27

              En tous cas ton i++ n'a rien à faire là, ta fonction ne peut pas fonctionner correctement avec.
              Je viens essayer ta fonction (en l'enlevant), et ça marche parfaitement...
              Tu as probablement mal alloué la mémoire pour tabc, montres comment tu gêres tout ça (finalement, drexil a raison en quelques sortes :p )
              • Partager sur Facebook
              • Partager sur Twitter
                12 janvier 2006 à 19:42:13

                Je viens de m'apercevoir d'une erreur dans mon main.
                Cela marche presque sauf qu'il reste encore un petit bug:
                http://img75.imageshack.us/img75/8408/bug0cu.jpg

                Voilà mon code avec le main + une fonction qui me sert à saisir (hum, ne vous posez pas trop de question sur cette dernière, c'est mon prof qui a exigé qu'on fasse ça. ^^;):

                #include "stdafx.h"
                #include <stdio.h>
                #include <conio.h>
                #define TAILLEMAX 30
                //Prototypages des fonctions
                void saisch(char *tabch);
                void concat(char *chaine1, char *chaine2, char *tabc);

                int main(void)
                {
                        char tabch[TAILLEMAX];
                        int i;
                        //initialisation du tableau
                        for(i=0;i<TAILLEMAX;i++)
                        {
                                tabch[i]=' ';
                        }
                        printf("Saisissez votre chaine de caractere\n");
                        saisch(tabch);   
                       
                        char tabch2[TAILLEMAX];
                        char tabc[TAILLEMAX*2]; //tableau qui va contenir le résultat de la concaténation
                        //initialisation du tableau
                        for(i=0;i<(TAILLEMAX*2);i++)
                        {
                                tabc[i]=' ';
                        }
                        printf("\n Saisissez une autre chaine\n");
                        saisch(tabch2);
                   
                        concat(tabch,tabch2,tabc);
                    for (i=0;i<(TAILLEMAX*2);i++)
                        {
                                printf("%c",tabc[i]);
                        }
                           
                        getch();
                        return 0;
                }

                void saisch(char *tabch)
                {
                        int ascii='a';
                        int i=0;
                        while(ascii!='\n')//des qu'on appuie sur entrée, la saisie s'arrête
                        {
                                ascii=getchar();//récupération du code ascii de la lettre saisie
                                tabch[i]=ascii;//on met le code ascii de la lettre saisie dans le tableau
                            i++;
                        }
                        tabch[i+1]='\0';
                               
                }



                void concat(char *chaine1, char *chaine2, char *tabc)
                {
                        int i=0;
                    int j=0;
                        while(chaine1[i]!='\0')
                        {
                                tabc[i]=chaine1[i];
                                i++;
                        }
                     
                        while(chaine2[j]!='\0')
                        {
                        tabc[i]=chaine2[j];
                                i++;
                                j++;
                        }
                   tabc[i+1]='\0';
                }
                • Partager sur Facebook
                • Partager sur Twitter
                  12 janvier 2006 à 20:03:46

                  Avec des pointeurs ce serait plus élégant, quelque chose comme :

                  void concat(char *d, const char *s1, const char *s2)
                  {
                          assert(d != NULL && s1 != NULL && s2 != NULL);
                          while (*s1 != '\0')
                                  *d++ = *s1++;
                          while ((*d++ = *s2++) != '\0')
                                  ;
                  }

                  • Partager sur Facebook
                  • Partager sur Twitter
                    12 janvier 2006 à 20:07:21

                    Salut. A quoi sert assert() et faut-il une librairie spéciale pour l'utiliser ?
                    • Partager sur Facebook
                    • Partager sur Twitter
                      12 janvier 2006 à 20:10:58

                      assert() c'est juste pour faire joli ^^
                      En fait je l'ai mis pour le fun ; ça permet d'affirmer qu'une condition est toujours vérifiée ; si tu compiles en mode debug, les assertions sont effectuées et le programme abort() si elles ne sont pas satisfaites, en mode ndebug, elles sont enlevées pour plus de perfs.

                      C'est dans la libc, mais faut inclure assert.h
                      • Partager sur Facebook
                      • Partager sur Twitter
                        12 janvier 2006 à 20:14:09

                        Ok, bo je viens d'essayer ton code à la place du mien et voilà les erreurs survenues lors de la génération:
                        edit: non s'bon, j'ai compris les erreurs.

                        par contre, ça ne marche plus du tout (plus de concaténation) et à la fin du débugage, j'ai ça:

                        Citation : Pas de titre

                        Run-Time Check Failure #2 - Stack around the variable 'tabch' was corrupted.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          12 janvier 2006 à 20:23:33

                          Tu as remarqué que j'avais passé la destination avant les sources ?
                          Exemple d'usage :

                          #include <stdio.h>
                          #include <stdlib.h>
                          #include <assert.h>

                          void
                          concat(char *d, const char *s1, const char *s2)
                          {
                                  assert(d != NULL && s1 != NULL && s2 != NULL);
                                  while (*s1 != '\0')
                                          *d++ = *s1++;
                                  while ((*d++ = *s2++) != '\0')
                                          ;
                          }

                          int
                          main(void)
                          {
                                  char d[20];
                                  char a[9] = "foo", b[9] = "bar";

                                  concat(d, a, b);
                                  printf("%s", d);

                                  return (0);
                          }
                          • Partager sur Facebook
                          • Partager sur Twitter
                            12 janvier 2006 à 20:27:37

                            Ah oui ! J'avais pas fait gaffe.

                            Bon j'ai testé et j'ai toujours le même petit bug. ^^;
                            • Partager sur Facebook
                            • Partager sur Twitter
                              12 janvier 2006 à 20:46:57

                              Hum, tu devrais coder de manière plus claire ton truc je pense, ta fonction saisch() est moisie, elle peut créer des overflows à volonté, tu as recréé gets() là...

                              Bon, regarde un exemple complet qui devrait faire quelque chose comme toi.

                              #include <stdio.h>
                              #include <stdlib.h>
                              #include <assert.h>

                              void
                              input(char *s, size_t n)
                              {
                                      int c;

                                      assert(s != NULL);
                                      if (n == 0)
                                              return;

                                      c = getchar();
                                      while (!(c == EOF && (feof(stdin) || ferror(stdin)))
                                             && c != '\n' && --n > 0) {
                                              /* C99 says this can invoke stupid behavior but we
                                                 don't much care... */

                                              *s++ = c;
                                              c = getchar();
                                      }
                                      *s = '\0';
                              }

                              void
                              concat(char *d, const char *s1, const char *s2)
                              {
                                      assert(d != NULL && s1 != NULL && s2 != NULL);
                                      while (*s1 != '\0')
                                              *d++ = *s1++;
                                      while ((*d++ = *s2++) != '\0')
                                              ;
                              }

                              #define L_LINEBUF 80

                              int
                              main(void)
                              {
                                      char d[L_LINEBUF * 2], a[L_LINEBUF], b[L_LINEBUF];

                                      input(a, L_LINEBUF);
                                      input(b, L_LINEBUF);

                                      concat(d, a, b);
                                      printf("%s", d);

                                      return (0);
                              }
                              • Partager sur Facebook
                              • Partager sur Twitter
                                12 janvier 2006 à 20:57:38

                                Ok, bon, il y a quelques trucs que je n'ai pas encore appris en cours donc je suis pas sur que mon prf les accepte.

                                Voici l'énoncé du tp: http://rpgworldfr.free.fr/cours/TPC04.doc
                                Il y a dedans les fonctions que l'on peut utiliser.

                                Merci pour l'aide.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  12 janvier 2006 à 20:59:56

                                  J'ai pas dit que j'allais te refaire ton exo mais je te montre juste comment je ferai moi. Ton code manque un peu de clarté : Trop de tableaux avec des indexes dans tous les sens est typiquement pas franchement lisible pour moi (avis perso).

                                  Tu devrais essayer de comprendre mon code mais c'était surtout pour montrer que ma fonction concat() n'avait aucun problème (en tout cas je n'en vois aucun), ça vient de toi...
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    12 janvier 2006 à 21:21:54

                                    Ok, bon alors il y a quelques trucs que je comprend pas:

                                    size_t n

                                    size_t, c'est un type ? o_O

                                    Et cette partie là:

                                    (feof(stdin) || ferror(stdin))

                                    Ca fait quoi ?

                                    Voilà, sinon, j'ai à peu près pigé to code.^^
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      12 janvier 2006 à 21:28:10

                                      size_t oui c'est le type standard pour spécifier les tailles et par extension ça sert bien pour spécifier le nombre d'éléments aussi. C'est déclaré dans divers headers dont stdlib.h

                                      feof(stdin) || ferror(stdin) ça teste s'il y a eu une erreur sur l'entrée standard ou si l'entrée standard est terminée mais à la rigueur, tu pourrais laisser juste c != EOF et ça marchera sur toutes les architectures ou presque (ça ne marchera pas potentiellement sur une architecture qui a des char de la taille des int et qui utilisent toutes les valeurs des char pour des caractères, ce qui en pratique ne semble pas exister)
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        12 janvier 2006 à 21:35:45

                                        Ok merci.
                                        A ce propos, c'est quoi EOF ?
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          12 janvier 2006 à 21:40:27

                                          End Of File, si tu veux quand tu appelles getchar(), il peut soit te retourner le prochain byte dans le flux, soit EOF s'il n'y a rien à lire ou s'il y a erreur. (Enfin, il y a un cas spécial mais bref)
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            12 janvier 2006 à 21:48:36

                                            End Of File

                                            EOF = -1

                                            -1 est la valeur renvoyée à une fonction quand ça foire, contrairement à 0, qui indique que tout s'est bien passé.

                                            Edit: bon visiblement c'était pas ça >_>
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              12 janvier 2006 à 22:01:38

                                              Merci bien.
                                              Vous m'avez appris plus de choses que mon prof. :lol:

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                12 janvier 2006 à 22:17:17

                                                Ça arrive souvent... personnellement, j'apprends plus de choses le soir sur msn en 4 heures qu'en un an d'SVT, et surtout c'est intéressant.
                                                • Partager sur Facebook
                                                • Partager sur Twitter

                                                Fonction concaténer

                                                × 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