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 :

generer les mots d'un alphabet (probleme avec strcat)


Sujet :

C

  1. #1
    Membre confirmé
    Inscrit en
    Mars 2006
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 87
    Par défaut generer les mots d'un alphabet (probleme avec strcat)
    Bonjour,

    Je cherche à faire un programme qui à partir d'un alphabet {a, b}, genere tous les mots possibles de taille inferieure ou egale à un entier "n".
    Par exemple pour n=2 :

    a; b; aa; ab; ba; bb.

    Pour cela, j'ai procédé de la maniere suivante:

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    void generer(char* mot, int n)
    {
        char* mot_a;
        char* mot_b;
     
        // J'ai essayé de mettre des malloc, mais ca ne ne donne rien :o).
        mot_a = (char*) malloc(n*sizeof(char));
        mot_b = (char*) malloc(n*sizeof(char));
     
        //on copie mot dans deux variables chaine de caractere. L'une pour
        //la concatener avec "a", l'autre avec "b".
        mot_a = mot;
        mot_b = mot;
     
        //condition d'arret du programme.
        if (n==0)
            exit(0);
     
    //debugage amateur
    printf("avant probleme\n");
     
        // On concatene la lettre "a" à mot_a, puis on l'affiche
        strcat(mot_a, "a");
     
    //debugage amateur
    printf("apres probleme\n");
     
        puts(mot_a);
     
        // on fait de meme avec mot_b et "b"
        strcat(mot_b, "b");
        puts(mot_b);
     
        //Appels recursifs pour generer les autres mots
        //On decremente n pour que le programme s'arrete quand n = 0
        generer(mot_a, n-1);
        generer(mot_b, n-1);
    }
     
    int main()
    {
        int n;
     
        printf("programme de generation de mots a partir de l'alphabet {a, b}\n");
        printf("Entrez N\n");
        scanf("%d", &n);
     
        // on donne un mot "vide" au depart.
        generer("", n);
     
        return 0;
    }
    Comme vous pourrez le constater dans le code (ou en executant le programme), ca plante juste apres le 1er strcat. En lancant le debuggeur (que je ne maitrise pas du tout) j'ai cru comprendre qu'il s'agissait d'une "segmentation fault".

    Voila voila. Alors si vous pouviez m'aider... Merci d'avance.

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Hum...

    C'est un beau bordel.
    1. Premièrement, on ne "copie" pas une chaîne avec = : = ne copie que le pointeur. Il faut utiliser strcpy() pour copier la chaîne.
    2. Ensuite, pense à mettre des const pour les pointeurs pointant vers quelque chose qui ne doit pas être modifié.
    3. Tu dois absolument définir ce que tu cherches à faire avant de l'implémenter en C. Écris l'algorithme de ce que tu veux faire et poste-le ici.
    4. Et supprime les casts du retour de malloc() : Ils sont inutiles et déconseillés en C.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par abdelhamidem Voir le message
    Bonjour,

    Je cherche à faire un programme qui à partir d'un alphabet {a, b}, genere tous les mots possibles de taille inferieure ou egale à un entier "n".
    Par exemple pour n=2 :

    a; b; aa; ab; ba; bb.

    Pour cela, j'ai procédé de la maniere suivante:

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    void generer(char* mot, int n)
    {
        char* mot_a;
        char* mot_b;
     
        // J'ai essayé de mettre des malloc, mais ca ne ne donne rien :o).
        mot_a = (char*) malloc(n*sizeof(char));
        mot_b = (char*) malloc(n*sizeof(char));
     
        //on copie mot dans deux variables chaine de caractere. L'une pour
        //la concatener avec "a", l'autre avec "b".
        mot_a = mot;
        mot_b = mot;
     
        //condition d'arret du programme.
        if (n==0)
            exit(0);
     
    //debugage amateur
    printf("avant probleme\n");
     
        // On concatene la lettre "a" à mot_a, puis on l'affiche
        strcat(mot_a, "a");
     
    //debugage amateur
    printf("apres probleme\n");
     
        puts(mot_a);
     
        // on fait de meme avec mot_b et "b"
        strcat(mot_b, "b");
        puts(mot_b);
     
        //Appels recursifs pour generer les autres mots
        //On decremente n pour que le programme s'arrete quand n = 0
        generer(mot_a, n-1);
        generer(mot_b, n-1);
    }
     
    int main()
    {
        int n;
     
        printf("programme de generation de mots a partir de l'alphabet {a, b}\n");
        printf("Entrez N\n");
        scanf("%d", &n);
     
        // on donne un mot "vide" au depart.
        generer("", n);
     
        return 0;
    }
    Comme vous pourrez le constater dans le code (ou en executant le programme), ca plante juste apres le 1er strcat. En lancant le debuggeur (que je ne maitrise pas du tout) j'ai cru comprendre qu'il s'agissait d'une "segmentation fault".
    Ouahou... ça part en torche là. Déjà premier truc => jamais de "exit" dans une fonction. On part du main pour aller dans la fonction => on quitte la fonction pour revenir au main (comme les poupées russes)

    Sinon j'ai pas trop le temps de suite mais plus tard dans la soirée je regarderai mieux l'algo...

    Citation Envoyé par Médinoc Voir le message
    [*]Et supprime les casts du retour de malloc() : Ils sont inutiles et déconseillés en C.
    Inutiles certainement. Mais pourquoi "déconseillés" ???
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Inutiles certainement. Mais pourquoi "déconseillés" ???
    Dangereux en cas d'oubli d'inclusion de stdlib.h, qu'ils masquent (le cast masque le warning de conversion d'entier en pointeur) :
    • Sur une architecture M68k, pointeurs et entiers ne sont pas retournés dans le même registre : Si le compilo croit que malloc() retourne un int parce qu'on n'a pas inclut stdlib.h, on aura n'importe quoi.
    • Sous Windows 64 bits, un int et un pointeur n'ont pas la même taille : On perdra donc les 32 bits supérieurs du pointeur.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Dangereux en cas d'oubli d'inclusion de stdlib.h, qu'ils masquent (le cast masque le warning de conversion d'entier en pointeur) :
    • Sur une architecture M68k, pointeurs et entiers ne sont pas retournés dans le même registre : Si le compilo croit que malloc() retourne un int parce qu'on n'a pas inclut stdlib.h, on aura n'importe quoi.
    • Sous Windows 64 bits, un int et un pointeur n'ont pas la même taille : On perdra donc les 32 bits supérieurs du pointeur.
    Jolie réponse très bien explicitée !!!
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Membre confirmé
    Inscrit en
    Mars 2006
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 87
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Hum...

    C'est un beau bordel.
    1. Premièrement, on ne "copie" pas une chaîne avec = : = ne copie que le pointeur. Il faut utiliser strcpy() pour copier la chaîne.
    2. Ensuite, pense à mettre des const pour les pointeurs pointant vers quelque chose qui ne doit pas être modifié.
    3. Tu dois absolument définir ce que tu cherches à faire avant de l'implémenter en C. Écris l'algorithme de ce que tu veux faire et poste-le ici.
    4. Et supprime les casts du retour de malloc() : Ils sont inutiles et déconseillés en C.
    Merci pour ton aide.

    Alors en fait l'algorithme tourne à peu pres comme ca pour generer des mots de taille <= 3 , toujours sur l'alphabet {a, b}
    le premier appel de generer se fait avec un mot vide, et n=3.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
                                    generer("", 3)
                                  /              \
                    generer("a", 2)               generer("b", 2)
                   /           \                      /        \
    generer("aa", 1)  generer("ab", 1)    generer("ba", 1)   generer("bb", 1)
    etc...

    Ce qui se passe dans generer("b", 2) c'est d'abord l'impression à l'ecran des deux mots "ba" puis "bb"...
    et ensuite il y a deux appels de generer(,):
    _ L'un pour afficher les mots qui viennent apres "ba", c'est à dire : "baa" puis "bab" ... puis faire les 2 appels de generer(,) qui font la suite de l'abrbre.
    _ L'autre pour afficher les mots qui viennent apres "ba", c'est à dire : "bba" puis "bbb"... puis faire les 2 appels de generer(,) qui font la suite de l'abrbre.

    J'utilise la concatenation car quand on appelle generer("b", 2) je concatene le mot "b" à la lettre "a", puis le mot "b" à la lettre "b", et je les affiche tous les 2. (ca donne "ba" puis "bb")

    J'espere que c'est plus clair maintenant.

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    OK.
    Donc, les mots générés sont immédiatement affichés et n'ont pas à être mémorisés.

    On sait aussi que la chaîne passée en paramètres est invariable : Le pointeur doit donc être const.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void generer_et_afficher(char const * mot, int n);
    Pour l'instant, on va se soucier de l'efficacité plutôt que de la performance : On va donc systématiquement utiliser malloc(), pour que le code marche avec des tailles arbitraires de mots. Mais dans la fonction, on n'utilisera qu'un seul buffer, par soucis de simplicité :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void generer_et_afficher(char const * const mot, int const n)
    {
    	/* Ici, le const est à droite de l'étoile: 
    	   C'est le pointeur lui-même qui est constant. */
    	char * const buf = malloc( sizeof(*buf) * (strlen(mot)+2) ); /* n caractères + 0 terminal */
    	if(buf != NULL)
    	{
    		/* Faire ce qu'il faut */
    		/* ... */
     
    		free(buf);
    	}
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Ensuite, il suffit de remplir avec le traitement correct :
    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
    void generer_et_afficher(char const * const mot, int const n)
    {
    	/* Ici, le const est à droite de l'étoile: 
    	   C'est le pointeur lui-même qui est constant. */
    	char * const buf = malloc( sizeof(*buf) * (strlen(mot)+2) ); /* longueur de mot + 1 + 0 terminal */
    	if(buf != NULL)
    	{
    		/* Faire ce qu'il faut */
    		strcpy(buf, mot);
    		strcat(buf, "a");
    		puts(buf);
    		generer_et_afficher(buf, n-1);
     
    		strcpy(buf, mot);
    		strcat(buf, "b");
    		puts(buf);
    		generer_et_afficher(buf, n-1);
     
    		free(buf);
    	}
    }
    Ce code suit l'arborescence, donc affichera ainsi:
    a
    aa
    ab
    b
    ba
    bb
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Inutiles certainement. Mais pourquoi "déconseillés" ???
    http://emmanuel-delahaye.developpez....tes.htm#malloc

  10. #10
    Membre confirmé
    Inscrit en
    Mars 2006
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 87
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Ensuite, il suffit de remplir avec le traitement correct :

    ...

    Ce code suit l'arborescence, donc affichera ainsi:
    a
    aa
    ab
    b
    ba
    bb
    Merci beaucoup pour ton aide! J'ai appliqué tes conseils, et ca marche à la perfection :o)

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 19/05/2013, 16h22
  2. probleme avec les mots en gras
    Par beghdad dans le forum Word
    Réponses: 17
    Dernier message: 30/09/2011, 00h57
  3. Réponses: 0
    Dernier message: 26/03/2010, 13h38
  4. probleme avec Strcat
    Par yassinert dans le forum C
    Réponses: 30
    Dernier message: 16/05/2007, 18h16
  5. Problème avec strcat
    Par Bahan dans le forum C
    Réponses: 5
    Dernier message: 22/05/2006, 14h08

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