IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Erreur de segmentation sur une chaine en récursif...


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 88
    Points : 53
    Points
    53
    Par défaut Erreur de segmentation sur une chaine en récursif...
    Bonsoir,

    j'ai une erreur de segmentation sur un code qui doit me permettre de supprimer les espaces avant, apres une chaine + ceux qui sont au minimum de 2
    ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    "       forum      Developpez.com                   "
    doit me retourner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    "forum Developpez.com"
    Je me suis lancé dans l'aventure du récursif :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    char
    *Ligne(char *cde,int i,int j)
    {
         char *l;
    //   printf("cde=%s i=%d j=%d\n",cde,i,j);
         if(i<strlen(cde)) return l;
         if(cde[i]==' ' && (j==0 || cde[i+1]==' ')) return Ligne(cde,i+1,j);
         return strcpy(l,Ligne(cde,i+1,j+1));
     }
    Voilà, si quelqu'un à une idée ?

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 88
    Points : 53
    Points
    53
    Par défaut
    Bon, j'ai fini par faire ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    char
    *Ligne(char *cde)
    {
         char l[255];
         int j=0, i=0;
         while(i<strlen(cde)) {
                 if(cde[i]==' ' && (j==0 || cde[i+1]==' ')) i++;
                 else {
                      l[j]=cde[i];
                      j++; i++;
                 }
         }
         l[j]='\0';
         cde=l;
         return cde;
    }
    C'est moins joli, mais ça marche
    Si toutefois quelqu'un à une idée pour mon premier code, je suis preneur.

    Laurent

  3. #3
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Ca marche, ça marche, à voir, tu retournes une adresse locale, qui risque donc de ne plus être valable à la toute fin d'exécution de la fonction.
    Ensuite, ta deuxième fonction n'est pas récursive.
    Le premier programme ne pouvait pas marcher puisque l était un pointeur non initialisé.
    Le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strcpy(l,Ligne(cde,i+1,j+1));
    ne pouvait que planter, de même pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(i<strlen(cde)) return l;

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut Re: Erreur de segmentation sur une chaine en récursif...
    Citation Envoyé par laurent_ifips
    Voilà, si quelqu'un à une idée ?
    Penser à fournir une chaine modifiable...

    Problème réglé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
     
    #define DBG 0
     
    static void clean_string_r (char *s, int r, int w, int in_word, int first)
    {
     
    #if DBG
       printf ("'%c' '%c' r=%2d w=%2d in_word=%d\n", s[r], s[w], r, w, in_word);
    #endif
     
       if (s[r] != 0)
       {
          if (in_word)
          {
             if (isspace (s[r]))
             {
                clean_string_r (s, r + 1, w, !in_word, first);
             }
             else
             {
                s[w] = s[r];
                clean_string_r (s, r + 1, w + 1, in_word, first);
             }
          }
          else
          {
             if (isspace (s[r]))
             {
                clean_string_r (s, r + 1, w, in_word, first);
             }
             else
             {
                if (first)
                {
                   s[w] = s[r];
                   clean_string_r (s, r + 1, w + 1, !in_word, !first);
                }
                else
                {
                   s[w] = ' ';
                   s[w + 1] = s[r];
                   clean_string_r (s, r + 1, w + 2, !in_word, first);
                }
             }
          }
       }
       else
       {
          s[w] = 0;
       }
    }
     
    static void clean_string (char *s)
    {
       clean_string_r (s, 0, 0, s[0] != ' ', 1);
    }
     
    int main (int argc, char **argv)
    {
       char s[] = "  forum\tDeveloppez.com   ";
     
       printf ("'%s'\n", s);
     
       clean_string (s);
     
       printf ("'%s'\n", s);
     
       if (strcmp (s, "forum Developpez.com") == 0)
       {
          printf ("\nP A S S E D\n");
       }
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    '  forum        Developpez.com   '
    'forum Developpez.com'
     
    P A S S E D

  5. #5
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Une autre variante, plus (b]itérative[/b]
    J'ajoute l'espace quand je commence un mot ce qui fait que forcement j'ai un espace au debut de la chaine dans le cas de notre chaine s...
    J'ai réussi à l'enlever en ajoutant un petit if...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    void fctrec(char *s, int idx, int cpidx, int whitespacecnt)
    {
          printf("Fctrec: %d %c %d %d %d\n",s[idx],s[idx],idx,cpidx,whitespacecnt);
          if(s[idx]=='\0')
          {
                s[cpidx]=s[idx];
          }
          else
                {
                if(s[idx]==' ')
                {
                  idx++;
                  whitespacecnt++;
                }
                else
                {
                        if(whitespacecnt)
                            {
                              if(cpidx)
                                    s[cpidx++] = ' ';
                              whitespacecnt=0;
                            }
     
                        s[cpidx++] = s[idx++];
                }
     
                fctrec(s,idx,cpidx,whitespacecnt);
                }
     
    }
     
    void clean_str_r(char *s)
    {
            fctrec(s,0, 0, 0);
    }
    Remarque: il y a biensur la solution de trouver l'indice du premier element qui n'est pas un espace et initialiser mon whitespacecnt pour que quand j'y arrive, il soit à 0 mais ca demanderait un premier parcours ce que je me suis refusé...

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par fearyourself
    Moi je suis partie dans l'autre sens, j'ajoute l'espace quand je commence un mot
    J'ai fini par adopter cette solution...
    ce qui fait que forcement j'ai un espace au debut de la chaine dans le cas de notre chaine s...
    Il suffit de ne pas insérer d'espace la premiere fois.

  7. #7
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Il suffit de ne pas insérer d'espace la premiere fois.
    Si tu regardes bien, c'est ce que je fais en utilisant l'indice de copie (ton w) ...

    Au final t'as un argument en plus et un test en plus...

    Maintenant viens la question, lequel des deux est mieux ou plus joli?

    Après si tu veux, on peut se lancer sur la version itérative... Quoique la vie est peut-être trop courte...

    Jc

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par fearyourself
    Il suffit de ne pas insérer d'espace la premiere fois.
    Si tu regardes bien, c'est ce que je fais en utilisant l'indice de copie (ton w) ...

    Au final t'as un argument en plus et un test en plus...

    Maintenant viens la question, lequel des deux est mieux ou plus joli?
    Je dirais que ta version est certes plus compacte, mais qu'elle met en oeuvre des opérateurs unaires (x++), ce qui va à l'encontre de la reflexion 'recursive' où on se contente en principe de passer des paramètres modifiés sans modifier les valeurs reçues...

    Ton codage est plus proche d'une approche itérative.

    Mon code est certainement simplifiable. (Mais comme tu le sous-entends, on a peut être pas que ça à faire !)

  9. #9
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Ton codage est plus proche d'une approche itérative.
    Et zut, j'ai été démasqué, c'est pour ça que j'ai du mal lorsqu'on me demande de faire du Caml, lol! Je suis d'accord, je crois que j'étais surpris que tu ne l'aies pas dit plus tôt en fait...

    -- Sujet clos --

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 88
    Points : 53
    Points
    53
    Par défaut
    Bonjour,

    Grand merci pour vos solutions que je vais regarder de plus près.
    J'ai l'impression que dans ce genre de problème la solution itérative est meilleure ?

    Au passage, vous utilisez quoi comme IDE/Debugger ?
    Moi je tourne sous VI et sans Debugger : à la fin c'est rasoir

    Merci

  11. #11
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par laurent_ifips
    J'ai l'impression que dans ce genre de problème la solution itérative est meilleure ?
    Une solution itérative est par définition plus sûre.
    Au passage, vous utilisez quoi comme IDE/Debugger ?
    Code::Blocks (Windows)

  12. #12
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par laurent_ifips
    Au passage, vous utilisez quoi comme IDE/Debugger ?
    Anjuta (Linux)

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 88
    Points : 53
    Points
    53
    Par défaut
    Merci, c'est installé

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XPATH 1.0] Erreur de segmentation sur une requête programmée en C avec libxml2
    Par BabzIm dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 26/05/2015, 16h28
  2. Erreur de segmentation sur une file
    Par memedplay dans le forum Débuter
    Réponses: 9
    Dernier message: 29/11/2013, 09h54
  3. Erreur de segmentation sur une concaténation
    Par cypher.sephiroth dans le forum Débuter
    Réponses: 14
    Dernier message: 18/08/2009, 17h42
  4. Erreur de segmentation sur une File
    Par hugo1992 dans le forum C
    Réponses: 2
    Dernier message: 22/10/2007, 08h49
  5. [Débutant][String] Opérations sur une chaîne
    Par gandalf_le_blanc dans le forum Général Java
    Réponses: 8
    Dernier message: 08/06/2004, 11h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo