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 :

Problème bus error


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 4
    Par défaut Problème bus error
    Je réalise un programme de recherche de mots dans une liste de mots, avec l'emploi des motifs '*' et '?'.
    Ex : si je cherche a*c, le programme me renvoie abc, aaac...

    Voici mon code :
    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
    79
    80
    81
    82
    83
    84
    85
    86
    87
     
    #include <stdio.h>
    #include <stdlib.h>
     
    #define TAILLE_MAX 100
     
    int masque(char *motif, char *string);
     
    int main(int argc, char *argv[])
    {
     
        FILE * fichier = fopen(argv[1],"r");
     
        char chaine[TAILLE_MAX];
        char * Tab[TAILLE_MAX];
        char * motif;
        char * string;
        int i=0;
     
        if (fichier == NULL)
        {
            printf("Erreur a l'ouverture\n");
            return 1;
        }
     
        if (fichier != NULL)
        {
            while (fgets(chaine, TAILLE_MAX, fichier) != NULL) // On lit le fichier tant qu'on ne reçoit pas d'erreur (NULL)
            {
                Tab[i]=chaine;
                i++;
            }
     
            fclose(fichier);
        }
     
     
        printf("Entrez votre motif de recherche : "); // On demande le motif à l'utilisatuer
        scanf("%s", motif);
     
        for (i=0; i<TAILLE_MAX; i++)
        {
            string = Tab[i];
            if(masque(motif, string)==1)  printf("%s", string); // On affiche le mot s'il correspond au motif
        }
     
    }
     
    int masque(char *motif, char *string)
    {
     
        const char *cc = NULL, *mc = NULL;
     
        while ((*string) && (*motif != '*'))
        {
            if ((*motif != *string) && (*motif != '?')) return 0;
            motif++;
            string++;
        }
     
        while (*string)
        {
            if (*motif == '*')
            {
                if (!*++motif) return 1;
                mc = motif;
                cc = string+1;
            }
     
            else if ((*motif == *string) || (*motif == '?'))
            {
                motif++;
                string++;
            }
            else
            {
                motif = mc;
                string = cc++;
            }
        }
     
        while (*motif == '*')
        {
            motif++;
        }
        return !*motif;
    }
    Je n'ai pas de problème à la compilation, mais quand je l'execute sous UNIX, j'obtiens un "bus error". Je pense que c'est dû à un problème d'écriture comme un segmentation fault, mais je ne sais pas comment le résoudre. Vous avez une piste de résolution ?

    Merci d'avance

  2. #2
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Je n'ai pas regardé en détail tout le code, mais le début pose problème :

    Lecture du motif
    Tu n'alloue pas de mémoire pour la variable motif. Tu as bien un pointeur, mais il ne pointe sur rien de valide.

    Écris char motif[TAILLE_MAX] plutôt que char *motif.

    Lecture du fichier
    Tu lis une chaine depuis le fichier puis tu veux la stocker dans le tableau, mais tu ne copie pas la chaine de caractères, tu ne fais que pointer sur la chaine dans laquelle tu as lu la ligne.

    La variable chaine reste constante tout au long du programme, mais la valeur pointée par chaine change.

    Au lieu de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
            {
                Tab[i]=chaine;
                i++;
            }
    Il aurait fallu écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
            while (fgets(chaine, TAILLE_MAX, fichier) != NULL) 
            {
                /* allocation de mémoire */
                Tab[i]= malloc(strlen(chaine)+1);
                /* copie de la ligne lue */
                strcpy(Tab[i], chaine);
                i++;
            }
    Edit
    N'hésite pas à ajouter des traces dans ton fichier pour savoir par où tu passe et où se situent les problèmes.
    Par exemple,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int masque(char *motif, char *string)
    {
        printf("Appel de masque(%s, %s)\n", motif, string);
        /* suite du code */

  3. #3
    Membre éclairé
    Inscrit en
    Avril 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Avril 2010
    Messages : 66
    Par défaut
    Bonjour,

    Compilé avec g++, cela ne fonctionne pas pour deux raisons : les const char* sont modifiés. Dans la fonction masque :
    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
    int masque(char *motif, char *string)
    {
     
        const char *cc = NULL, *mc = NULL;
     
        while ((*string) && (*motif != '*'))
        {
            if ((*motif != *string) && (*motif != '?')) return 0;
            motif++;
            string++;
        }
     
        while (*string)
        {
            if (*motif == '*')
            {
                if (!*++motif) return 1;
                mc = motif;
                cc = string+1;
            }
     
            else if ((*motif == *string) || (*motif == '?'))
            {
                motif++;
                string++;
            }
            else
            {
                motif = mc;
                string = cc++;
            }
        }
     
        while (*motif == '*')
        {
            motif++;
        }
        return !*motif;
    }
    Essaye déjà de retirer les 'const'.
    Edit : Ah, grillé ^^

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 4
    Par défaut
    Merci bien pour l'aide

    Quand je lance l'execution, j'arrive à ouvrir un fichier (qui comporte un mot par ligne), je parviens à entrer mon motif de recherche, et le programme marche parfois (mais ça c'est le problème de ma fonction "masque" qui doit être un peu erronée).

    Mais j'obtiens toujours après mon résultat un "bus error". Je me demande si c'est parce que j'alloue top de place au tableau, et si je devrais par exemple faire un compteur de ligne pour réparer tout ça.

    Pour rappel, mon code :
    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
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <strings.h>
     
    #define TAILLE_MAX 100
     
    int masque(char *motif, char *string);
     
    int main(int argc, char *argv[])
    {
     
        FILE * fichier = fopen(argv[1],"r");
     
        char chaine[TAILLE_MAX];
        char * Tab[TAILLE_MAX];
        char motif[TAILLE_MAX];
        char * string;
        int i=0;
     
        if (fichier == NULL)
        {
            printf("Erreur a l'ouverture\n");
            return 1;
        }
     
        if (fichier != NULL)
        {
            while (fgets(chaine, TAILLE_MAX, fichier) != NULL) // On lit le fichier tant qu'on ne reçoit pas d'erreur
            {
                Tab[i]= malloc(strlen(chaine)+1); // allocation de mémoire
                strcpy(Tab[i], chaine); // copie de la ligne lue
                i++;
            }
     
            fclose(fichier);
        }
     
     
        printf("Entrez votre motif de recherche : "); // On demande le motif à l'utilisateur
        scanf("%s", motif);
     
        for (i=0; i<TAILLE_MAX; i++)
        {
            strcpy(string, Tab[i]);
     
            if(masque(motif, string)==1)  // On affiche le mot s'il correspond au motif
            {
                printf("%s\n", string);
            }
        }
     
    }
     
    int masque(char *motif, char *string)
    {
        printf("Appel de masque(%s, %s)\n", motif, string);
     
        char *cc, *mc;
     
        while ((*string) && (*motif != '*'))
        {
            if ((*motif != *string) && (*motif != '?'))
            {
                return 0;
    		}			
            motif++;
            string++;
        }
     
        while (*string)
        {
            if (*motif == '*')
            {
                if (!*++motif)
                {
                    return 1;
    			}
                mc = motif;
                cc = string+1;
            }
     
            else if ((*motif == *string) || (*motif == '?'))
            {
                motif++;
                string++;
            }
            else
            {
                motif = mc;
                string = cc++;
            }
        }
     
        while (*motif == '*')
        {
            motif++;
        }
        return !*motif;
    }

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Mais j'obtiens toujours après mon résultat un "bus error". Je me demande si c'est parce que j'alloue top de place au tableau, et si je devrais par exemple faire un compteur de ligne pour réparer tout ça.
    Evidemment, le tableau de pointeurs Tab n'est en général que partiellement rempli, le reste contenant n'importe quoi ce qui va faire planter le programme.

    Tu as déjà fait un compteur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            while (fgets(chaine, TAILLE_MAX, fichier) != NULL) // On lit le fichier tant qu'on ne reçoit pas d'erreur
            {
                Tab[i]= malloc(strlen(chaine)+1); // allocation de mémoire
                strcpy(Tab[i], chaine); // copie de la ligne lue
                i++;
            }
    Il suffit de sauvegarder la valeur de i en sortie de boucle et utiliser cette valeur à la place de TAILLE_MAX ensuite.

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 4
    Par défaut
    J'ai progressé et maintenant mon programme marche "à peu près"

    Il ne me reste que deux erreurs :

    - mon programme ne prend pas en compte les deux premiers mots de mon fichier (qui est composé de mots séparés par des espaces) : je soupçonne un problème d'initialisation dans les boucles, mais j'ai regardé de fond en comble, et je n'ai pas trouvé.

    - tous mes motifs de recherche fonctionnent, sauf quand je commence mon motif par un caractère '*'. Pourtant, j'ai testé la fonction masque seule, en dehors du main et il n'y a pas ce problème..

    Voici mon code :
    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
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    /* programme écrit par Antoine Depreux
    derniere version : 07/11/2010 */
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <strings.h>
     
    #define TAILLE_MAX 50
     
    int masque(char *motif, char *string);
     
    int main(int argc, char *argv[]) {
     
        FILE * fichier = fopen(argv[1],"r");
     
        char chaine[TAILLE_MAX];
        char * Tab1[TAILLE_MAX];
        char motif[TAILLE_MAX];
        char string[TAILLE_MAX];
        char ** Tab2;
     
        int i=0, j, Compteur;
        int reponse=1;
     
        // erreur a l'ouverture
        if (fichier == NULL) {
            printf("Erreur a l'ouverture. Utilisation : entrer en argument le nom du fichier\n");
            return 1;
        }
     
        // lecture du fichier et copie dans Tab
        if (fichier != NULL) {
            while (fscanf(fichier,"%s", chaine) != EOF)  { // On lit le fichier tant qu'on ne recoit pas d'erreur
                Tab1[i]= (char *)malloc(sizeof(char)*(strlen(chaine)+1)); // allocation de memoire
                strcpy(Tab1[i], chaine); // copie du mot lu
                i++;
            }
     
            Compteur = i; // on recupere le nombre de mots total
     
            Tab2=malloc(Compteur); // allocation de memoire
     
            // copie dans le tableau de taille Compteur
            for(j=0; j<Compteur; j++) {
                Tab2[j]=(char *)malloc(sizeof(char)*(strlen(Tab1[j])+1));
                strcpy(Tab2[j], Tab1[j]);
            }
     
            free(Tab1);
            fclose(fichier);
        }
     
        // lectur du motif et appel a la fonction masque
        while(reponse==1) {
            printf("Entrez votre motif de recherche : "); // On demande le motif a l'utilisateur
            scanf("%s", motif);
     
            for (i=0; i<Compteur; i++) { // On affiche le mot s'il correspond au motif
                if(masque(motif, Tab2[i])==1) {
                    printf("%s\n", Tab2[i]);
                }
            }
     
            printf("Recherche terminee.\nNouvelle recherche ? (1:oui, 0:non) ");
            scanf("%d",&reponse);
        }
     
    }
     
    // fonction masque qui retourne 1 si motif et string correspondent, 0 sinon
    int masque(char *motif, char *string) {
     
        //printf("Appel de masque(%s, %s)\n", motif, string);
     
        char *cc, *mc;
     
        while ((*string) && (*motif != '*')) { // si le motif ne vaut pas * : on passe au caractere suivant
            if ((*motif != *string) && (*motif != '$')) return 0; // si le motif n'est pas bon et ne vaut pas $ : masque renvoie 0
     
            motif++;
            string++;
        }
     
        while (*string) {
            if (*motif == '*') { // le motif vaut * : on range dans mc le motif et dans cc le caractere suivant
                if (*(++motif) == 0) return 1; // on arrete le processus a la fin du motif
     
                cc = string+1;
                mc = motif;
            }
     
            else if ((*motif == *string) || (*motif == '$')) { // le motif est bon ou vaut $ : on compare le caractere suivant au motif suivant
                string++;
                motif++;
            }
     
            else { // le motif n'est pas bon, et ne vaut pas * ou $
                string = cc++;
                motif = mc;
            }
        }
     
        while (*motif == '*') { // si le motif est un *, on passe au motif suivant
            motif++;
        }
     
        if (*motif == 1) return 0; // on s'arrete avant la fin : masque renvoie 0
        else return 1;
    }

  7. #7
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Il y a des erreurs :
    1-
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tab2=malloc(Compteur); // allocation de memoire
    tu devrais avoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Tab2=malloc(Compteur*sizeof(char*)); // allocation de memoire
    // ou
    Tab2=malloc(Compteur*sizeof *Tab2); // allocation de memoire
    2- Tab1 n'a pas été alloué dynamiquement, ce sont les Tab1[i] qui l'ont été et sur lesquel il faudrait faire les free().

    3- Pourquoi faire deux fois l'allocation dynamique pour une chaine ? Une fois qu'elle a été faite en utilisant Tab1, et que Tab2 a été alloué, il suffit de copier les Tab1[i] dans les Tab2[i]. En plus, il n'y a plus à faire de désallocation des Tab1[i], d'allocation pour les Tab2[i], de copie des chaines puisque seule leur adresse est copiée.

Discussions similaires

  1. Problème constraint error
    Par Vivian Pennel dans le forum Ada
    Réponses: 13
    Dernier message: 16/11/2006, 16h17
  2. [Débutant] Bus Error et scanf
    Par BiLLKiLL dans le forum C
    Réponses: 2
    Dernier message: 17/09/2006, 20h47
  3. Réponses: 4
    Dernier message: 21/07/2006, 15h33
  4. bus error sur une machine SUN
    Par mhtrinh dans le forum C
    Réponses: 14
    Dernier message: 10/07/2006, 16h43
  5. bus error
    Par salseropom dans le forum C
    Réponses: 3
    Dernier message: 15/12/2005, 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