Probleme de liste chainée en C
Fermé
Bastien
-
20 oct. 2005 à 15:46
mamiemando Messages postés 33432 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 16 décembre 2024 - 20 oct. 2005 à 23:55
mamiemando Messages postés 33432 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 16 décembre 2024 - 20 oct. 2005 à 23:55
A voir également:
- Probleme de liste chainée en C
- Liste déroulante excel - Guide
- Liste déroulante en cascade - Guide
- Liste de diffusion whatsapp - Guide
- Gertrude a préparé la liste des affaires à prendre pour l'excursion. juliette a modifié cette liste en utilisant le mode suivi des modifications proposé par le traitement de texte. - Guide
- Liste groupe whatsapp - Guide
2 réponses
mamiemando
Messages postés
33432
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
16 décembre 2024
7 809
20 oct. 2005 à 21:04
20 oct. 2005 à 21:04
Quand tu poste du code, mets le entre des balises de mise en forme "code" histoire que ce soit lisible ;-)
Je te propose un code mais je ne peux pas le compiler et te dire s'il marche... Mais à mon avis on n'est pas loin du vrai ;-)
Bonne chance
Je te propose un code mais je ne peux pas le compiler et te dire s'il marche... Mais à mon avis on n'est pas loin du vrai ;-)
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct voisinage { int ordre; int *v; struct voisinage *suiv; }voisinage; voisinage *new_voisinage(){ voisinage *vois=(voisinage *)calloc(1,sizeof(voisinage)); return vois; } void del_voisinage(voisinage *vois){ free(vois.v); free(vois); } void del_chaine(voisinage *debut){ voisinage *vois=debut; voisinage *vois_suivant; while(vois){ vois_suivant=vois->suivant; del_voisinage(vois); vois=vois_suivant; } } //------------------------------------------------- int *lire_ligne(char *str){ //1er passage : déterminer le nombre d'entiers : unsigned int nb_elts,i; int plop; int *tab; for(nb_elts=0;sscanf(buffer," %d ",&plop)==1;++nb_elts); printf("La ligne [%s] contient %d element(s)\n",buffer,nb_ets); //2e passage : remplir le tableau tab=(int *)malloc(nb_elts*sizeof(int)); for(i=0;i<nb_elts;++i){ sscanf(buffer," %d ",&tab[i]); } return tab; } int lire_fichier(fp){ unsigned int ordre_lu; voisinage *vois_suivant; voisinage *vois_courant; char buffer[255]; //1ere ligne fscanf("%d\n",&ordre_lu); vois_courant=new_voisinage(ordre_lu); //Lignes suivantes while(!feof(fp)){ fscanf("%s\n",&buffer); printf("Lit %s\n",buffer); vois_courant->v=lire_ligne(buffer); vois_suivant=new_voisinage(vois_courant->ordre+1); vois_courant->suivant=vois_suivant; vois_courant=vois_suivant; } return 0; } int main(int argc, char **argv){ FILE *fp; voisinage *vois; if (argc!=1){ fprintf(stderr,"usage : %s filename\n",argv[0]); return 1; } if( (fp=fopen(argv[1])==NULL){ fprintf(stderr,"Fichier %s invalide\n",argv[1]); return 1; } vois=lire_fichier(fp); del_chaine(vois); return 0; }
Bonne chance
crabs
Messages postés
908
Date d'inscription
lundi 18 avril 2005
Statut
Membre
Dernière intervention
3 août 2008
507
20 oct. 2005 à 21:04
20 oct. 2005 à 21:04
Salut,
Vu ton code tu fais de graves erreurs sur la gestion des compteurs ;-)
Déja au niveau de la fonction ( je rajoute quelques commentaires)
Si dans le code d'entrée de ta fonction, la liste voisinage doit être vide, pas
la peine de la passer en argument, ou alors comme argument de sortie.
Mais avant de continuer sur ce point regardons de plus près le codage
du passage d'arguement
La déclaration globale réserve dans l'espace de données de ton programme
une cellule voisinage.
L'appel dans ton main avec &vois, passe à la fonction l'adresse de cette
cellule à la fonction (c'est valide vis à vis du compilateur).
Le programme entre dans la fonction CreerFVoisinage, il met dans la variable
vsng la copie de cette adresse (copie que tu modifie via un malloc qui sert
à rien, puis une remise à null).
La fonction revient dans le main() et là surprise l'adresse de 'vois' n'a pas
changé, donc ta fonction affiche...() ne connait pas la valeur correcte qu'a
pu élaborer Creer...().
Y a plusieurs solution pour résoudre ça, je te présente celle qui me semble
la plus simple.
Le prototype de la fonction Creer...() devient :
Et là le code de ton main devient, après suppression de la déclaration de
la variable globale vois
Ca devrait être plus correct au niveau de la gestion de tes pointeurs et des
fonctions. Je ne présume pas que le traitement soit OK.
Sinon si tu veux absolument passer l'ancre de ta liste chainée en argument,
il faut utiliser un pointeur sur un pointeur de voisinage (voisinage **pt dans
le prototype de la fonction, voisinage*vois dans la déclaration pour le main,
&vois lors de l'appel, et utiliser *vois dans la fonction).
A+, bon courage, crabs
Vu ton code tu fais de graves erreurs sur la gestion des compteurs ;-)
Déja au niveau de la fonction ( je rajoute quelques commentaires)
int CreerFVoisinage(char *nom,voisinage *vsng) { int o,i; voisinage *p; FILE *f; vsng=(voisinage *) malloc(sizeof(voisinage)); /* allocation d'une cellule voisinage */ vsng=NULL; /* mise à null du pointeur */ /* la cellule précédement alloué est perdue, elle est alloué mais on sait plus où elle est */
Si dans le code d'entrée de ta fonction, la liste voisinage doit être vide, pas
la peine de la passer en argument, ou alors comme argument de sortie.
Mais avant de continuer sur ce point regardons de plus près le codage
du passage d'arguement
/* en global */ voisinage vois; /* la fonction */ int CreerFVoisinage(char *nom,voisinage *vsng) { } /* la fonction main() */ int main(int argc,char **argv) { CreerFVoisinage("Fvsng.txt",&vois); afficheVoisinage(&vois); return 0; }
La déclaration globale réserve dans l'espace de données de ton programme
une cellule voisinage.
L'appel dans ton main avec &vois, passe à la fonction l'adresse de cette
cellule à la fonction (c'est valide vis à vis du compilateur).
Le programme entre dans la fonction CreerFVoisinage, il met dans la variable
vsng la copie de cette adresse (copie que tu modifie via un malloc qui sert
à rien, puis une remise à null).
La fonction revient dans le main() et là surprise l'adresse de 'vois' n'a pas
changé, donc ta fonction affiche...() ne connait pas la valeur correcte qu'a
pu élaborer Creer...().
Y a plusieurs solution pour résoudre ça, je te présente celle qui me semble
la plus simple.
Le prototype de la fonction Creer...() devient :
voisinage* CreerFVoisinage(char *nom) { voisinage* vsng = null ; /* le reste de ton code, retourne null en cas d'erreur système à l'open */ .... /* à la fin tu retourne l'ancre de ta liste */ return vsng ; }
Et là le code de ton main devient, après suppression de la déclaration de
la variable globale vois
int main(int argc,char **argv) { voisinage* vois ; vois = CreerFVoisinage("Fvsng.txt"); afficheVoisinage(vois); /* ne pas oubllier de faire une fonction qui libère la mémoire allouée */ return 0; }
Ca devrait être plus correct au niveau de la gestion de tes pointeurs et des
fonctions. Je ne présume pas que le traitement soit OK.
Sinon si tu veux absolument passer l'ancre de ta liste chainée en argument,
il faut utiliser un pointeur sur un pointeur de voisinage (voisinage **pt dans
le prototype de la fonction, voisinage*vois dans la déclaration pour le main,
&vois lors de l'appel, et utiliser *vois dans la fonction).
A+, bon courage, crabs
20 oct. 2005 à 21:07
20 oct. 2005 à 23:55