Pb de recherche dans une liste chainée

elwess20 Messages postés 28 Statut Membre -  
KX Messages postés 19031 Statut Modérateur -
Bonjour mes amis,
j'ai fait un programme qui permet de stocker une fichier dans une liste chainée,mais le problème ,c'est quand j'ai en train de rechercher un mot dans cette liste ,il me dit un erreur de segmentation,j'ai pas trouvé cette erreurs,alors dans ma liste il y a l2 champs,un champ pour le fait et l'autre pour règle,la liste de fait affiche rouge noir blanc rose.Et le champ règle affiche seulement gris rouge foncée,si je veut faire un recherche dans la liste de fait le noir ou blanc,il m'affiche gris,mais toujours il me dit que c'est un erreur de segmentation,s'il vous plait aidé moi,je vous donne le fichier texte et le programme de recherche :
tab variable qui extrait la liste des mots de fait,et la variable mot extrait la liste des règles dans le fichiers

donnée.txt
fait
rouge,noir,blanc,rose
regle
si blanc et noir alors gris
si rouge et noir alors rouge foncée


prog.c
while (tab !=NULL)
                       {
                        tab = strtok(NULL,separateur);
                        Nouveau=(Liste*)malloc(sizeof(Liste));                      /*allocation d'un maillon listeNouveau pour mettre les fait */
                        tete=NULL;
                        Nouveau->fait=tab;                                          
                        Nouveau->regle=mot;
                        Nouveau->psuivant = tete;

                        tete=Nouveau;
                              if(tab != NULL )                                      /* allocation de maillon pcourant pour mettre les regles dans la liste*/
                               {
                                pcourant=(Liste*)malloc(sizeof (Liste));
                                pcourant->fait=tab;
                                pcourant->regle=mot;

                                       if(tete!=NULL)
                                         {
                                           pcourant=tete;
                                           while(pcourant->psuivant != NULL)
                                           Nouveau->psuivant=pcourant;
                                         }
                                 pcourant2=tete;
                                      while(pcourant2->psuivant->fait!="noir")              /*parcours de la liste pour l'affichage des regle et des fait*/
                                     {  
                                      pcourant2=pcourant2->psuivant;
                                      }
                                }
                                 printf("%s\n",pcourant2->regle);                                  /*c'est ici l'erreur de segmentation*/         
                        } 


merci pour votre aide

5 réponses

KX Messages postés 19031 Statut Modérateur 3 020
 
Je suppose que tu utilises la même structure qu'hier, malheureusement comme tu as modifié tous tes messages pour "cacher ton code", on ne sais pas comment sont initialisées tes variables (tab, mot, pcourant2...)

Hier on en était resté à dire que tete n'était pas initialisée, ici il se pourrait que ce soit le même genre d'erreur, est-ce que pcourant2->regle est initialisé avant l'affichage ?

PS. Sans code complet, je ne peux pas t'aider plus, puisque je ne peux pas tester...
0
elwess20 Messages postés 28 Statut Membre
 
dsl pour la modification de mes message puisque j'ai bien modifié le code et je vous remettre le code complet ci dessous,et merci

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct Liste Liste;                                         /* declaration de liste chainée*/
struct Liste {
               char *fait;
               char *regle;
               struct Liste* psuivant;
              };

int main(void) 
{
 Liste *Nouveau,*pcourant,*tete,*pcourant2;                       /*declaration de 3 pointeurs qui pointe sur la liste*/
 FILE *fp;                                                        /*declaration des variable*/
 int nbre;
 char *regle;
 char *x;
 char nom[50];
 char nomA[50];
 char nomc[50];
 char mot[BUFSIZ];
 char buffer[BUFSIZ];
 char *tab;
 char *recherche;
 char *separateur = { "," };
 fp=fopen("donnee.txt","r");                                     /*ouverture de fichier*/
    if(fp==NULL)
     { 
		fputs("erreur à l'ouverture du fichier\n",stderr);
		return EXIT_FAILURE; 
     }

        while(fgets(buffer, sizeof(buffer),fp))                  /*parcour de la pointeur buufer dans le fichier*/
        {
        char *c=strchr(buffer,'\n');                             /*eliminé les retour de lignes dans le fichier*/
                 if(c!=NULL)
                 {
                  *c='\0';
                 }
        if(strstr(buffer,"alors")==0)                            /*recherche de mot alors pour extraire la regle*/ 
		{ 
                       fseek(fp,6,SEEK_CUR);  
                       fgets(mot,100,fp);
                       
		}
        tab = strtok(buffer,separateur);                         /*extraction de mot qui sont separer par le separateur donnée,c'est pour extraire les mot de fait*/
                      while (tab !=NULL)
                       {
                        tab = strtok(NULL,separateur);
                        Nouveau=(Liste*)malloc(sizeof(Liste));                      /*allocation d'un maillon listeNouveau pour mettre les fait */
                        tete=NULL;
                        Nouveau->fait=tab;                                          
                        Nouveau->regle=mot;
                        Nouveau->psuivant = tete;

                        tete=Nouveau;
                              if(tab != NULL )                                      /* allocation de maillon pcourant pour mettre les regles dans la liste*/
                               {
                                pcourant=(Liste*)malloc(sizeof (Liste));
                                pcourant->fait=tab;
                                pcourant->regle=mot;

                                       if(tete!=NULL)
                                         {
                                           pcourant=tete;
                                           while(pcourant->psuivant != NULL)
                                           Nouveau->psuivant=pcourant;
                                  }
                       
                                 pcourant2=tete;
                                      while((pcourant2->psuivant!=NULL) ||(pcourant2->fait!="noir))             /*parcours de la liste pour l'affichage des regle et des fait*/
                                     {  
                                      pcourant2=pcourant2->psuivant;
                                      printf("%s\n",pcourant2->regle
                                      }

                                }
                                                     
                        } 
                           
        } 

 
0
KX Messages postés 19031 Statut Modérateur 3 020
 
C'est peut-être juste un problème de recopie, mais la fin du code est pleine d'erreur :

    while((pcourant2->psuivant!=NULL) ||(pcourant2->fait!="noir")) 
    {  
        pcourant2=pcourant2->psuivant;
        printf("%s\n",pcourant2->regle);
    }
   }
  } 
 } 
 return 0;
}

De plus, nbre, regle, x, nom, nomA,nomc, recherche ne sont pas utilisées.

Sinon, if (strstr(buffer,"alors")==0) est incorrect.
Il accepte par exemple "fait" alors qu'il ne devrait pas...
Tu devrais plutôt utiliser, if (strstr(buffer,"alors")!=NULL)
Du coup, mot ne sera jamais initialisé avant d'avoir vu "alors" dans le fichier.
En conséquence Nouveau->regle=mot n'est pas initialisé.
De même pour pcourant->regle=mot.

De plus, tu as fait tete=NULL
Nouveau->psuivant= tete
Puis tete = Nouveau
En conséquence, on a tete->psuivant==NULL
Puis vient ton affectation pcourant2=tete
On a forcément pcourant2->psuivant==NULL
Or tu fais un test while((pcourant2->psuivant!=NULL) ||(pcourant2->fait!="noir"))
Ce test renvoie évidemment vrai, car même si pcourant2->fait contient la valeur vrai, on ne teste pas deux chaînes de caractères avec le symbole !=
Du coup tu rentres dans ton while, tu fais pcourant2=pcourant2->psuivant
Donc pcourant2==NULL
Et là patatras : printf("%s",pcourant2->regle)
0
elwess20 Messages postés 28 Statut Membre
 
merci beaucoup pour votre réponse.
Pour l'erreur de strstr je l'ai corrigé,et pour les variables je les utilisé mais j'ai oublié de les supprimer,
pour le mot,est ce qu'il faut initialisée avant le test de buffer ?
mot="";

pour la liste chainée,je ne sais pas comment faire,est ce que je déclare un autre pointeur au lieu de pointeur tete,et je laisse le pointeur tete au debut de la liste?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
KX Messages postés 19031 Statut Modérateur 3 020
 
Pour mot ça pourrait suffire.

Pour la liste la modification de ta condition dans le while est nécessaire.
Déjà en remplacant ton !="noir" par strcmp()!=0, mais aussi en plaçant un && au lieu du ||

Sinon, je ne sais pas ce qu'est censé faire ton code, mais l'utilisation de fonctions intermédiaires pour manipuler des listes (consultation, ajout et suppression) ne serait pas négligeable vu le casse-tête de pointeurs intermédiaires que tu as fais.
0