Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1420 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Liste doublement chainée

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Liste doublement chainée

n°1692990
silver5300​0
Posté le 26-02-2008 à 18:44:22  profilanswer
 

Bonjour, je vais aller au plus simple :
 
J'ai un fichier texte (contact.txt) de la forme "nom prenom 0601012222 email@mail.fr" sur chaque ligne.
Je voudrais dans un premier temps rentrer chaque contact dans une cellule d'une liste doublement chainée et circulaire. Malheureusement je ne maitrise pas les listes chainées.
Voici ce que j'ai fait :  
 

Code :
  1. typedef struct contact{ // on définit une structure pour y rentrer les contacts issus du fichier contact.txt
  2. char nom[30];
  3. char prenom[30];
  4. char numero[30];
  5. char email[30];
  6. }contact;
  7. typedef contact* ptr_contact; // on définit un poiteur sur la structure contact
  8. void récupérer_contact(contact *contact1)
  9. int trier_contact();
  10. int carlu;
  11. contact nouveau_contact;
  12. FILE* fichier=NULL;
  13. fichier=fopen("contact.txt","r" ); // on ouvre le fichier contact.txt
  14. if(!fichier)
  15.  printf("erreur" );  // lorsque l'ouverture du fichier echoue
  16. else
  17. {
  18.  do
  19.  {
  20.   carlu=fscanf(fichier, %s %s %s %s , ptr_contact.nom, ptr_contact.prenom, ptr_contact.numero, ptr_contact.email); // on rentre les données dans la structure
  21.   toupper
  22.   trier_contact(contact1, nouveau_contact)
  23.  }
  24.  while(carlu!=EOF)
  25. fclose(fichier);


 
A noter que j'ai utilisé une fonction (trier_contact) qui me servira à trier la liste chainée dans l'ordre alphabétique des noms.
 
Merci pour votre aide


Message édité par silver53000 le 26-02-2008 à 20:15:34
mood
Publicité
Posté le 26-02-2008 à 18:44:22  profilanswer
 

n°1692999
MagicBuzz
Posté le 26-02-2008 à 18:54:43  profilanswer
 

je vois pas trop ce que tu veux faire avec une "liste chaînée circulaire"...
 
en tout cas, pour faire une liste chaînée "simple", il faut que ta struct comporte un pointeur sur le type de ta struct, qui servira à stocker un lien vers le contact "fils".
et pour une liste chaînée double, bah c'est pareil, sauf qu'il faut deux pointeurs, un pour le fils et un pour le père.
 
ensuite il faut simplement une fonction "inserer(*contact fils, *contact pere);"
=> et elle s'occupe de rechercher le père, lui colle comme fils le nouveau contact, qui prend elle-même l'ancien fils du père pour fils, et pour père, le père.
 
pour ce qui est de "trier", si ta liste est réellement circulaire, je ne vois pas trop comment tu veux trier ça, en tout cas, un tri se fera à grands coups de permutations utilisant ta fonction inserer() et enlever() (qui s'occupe de lier le fils et le père d'un contact ensembler et allourer 0 comme pointeurs père et fils à ton pointeur enlevé)


Message édité par MagicBuzz le 26-02-2008 à 18:56:20
n°1693011
silver5300​0
Posté le 26-02-2008 à 19:09:11  profilanswer
 

Oui tout compte fait, ce n'est pas utile que la liste chainée soit circulaire, le but de la liste chainée étant :
Partir d'un fichier de contacts non trié,  
Rentrer les contacts dans une liste chainée,  
Trier celle-ci,  
Réécrire le fichier dans l'ordre alphabétique.
 
Je sais théoriquement comment fonctionne un liste chainée, avec un pointeur sur suivant et un autre sur précédent, mais je n'arrive pas à mettre celà en application avec un fichier (rentrer les données du fichier dans la liste chainée)

n°1693020
tpierron
Posté le 26-02-2008 à 19:24:11  profilanswer
 

man sort

n°1693055
bjone
Insert booze to continue
Posté le 26-02-2008 à 20:08:44  profilanswer
 

ton code est foireux (outre que y'a eu des problèmes de copier/coller, enfin j'espère).
 
char carlu;
 while(carlu=!EOF)
 
pour contenir le code eof, il faut passer par un int.
!= au lieu de =!  
 
 
 
 

n°1693061
silver5300​0
Posté le 26-02-2008 à 20:16:19  profilanswer
 

ok je vais reprendre tout ça avec mon poly de cours et reposter une solution

n°1693078
silver5300​0
Posté le 26-02-2008 à 21:01:14  profilanswer
 

Code :
  1. typedef struct contact{ // on définit une structure pour y rentrer les contacts issus du fichier contact.txt
  2. char nom[30];
  3. char prenom[30];
  4. char numero[30];
  5. char email[30];
  6. struct contact *suivant;
  7. struct contact *precedant;
  8. }contact;
  9. void récupérer_contact(contact *contact1)
  10. #define TAILLE_MAX 30
  11. contact *contact_1=NULL;
  12. int carlu;
  13. contact lesContacts[TAILLE_MAX];
  14. int i=0;
  15. FILE* fichier=NULL;
  16. fichier=fopen("contact.txt","r" ); // on ouvre le fichier contact.txt
  17.  if(!fichier)
  18.   printf("erreur" );  // lorsque l'ouverture du fichier echoue
  19.  else
  20.  {
  21.   do
  22.   {
  23.    for (i=0; i<=1000; i++)
  24.    {
  25.     carlu=fscanf(fichier, "%s %s %s %s", lesContacts[i].nom, lesContacts[i].prenom, lesContacts[i].numéro, lesContacts[i].email);// on rentre les données dans la structure
  26.         }
  27.   }
  28.   while(carlu!=EOF)
  29.  }
  30.  fclose(fichier);


 
bon j'ai rentré les données du fichier dans un tableau de structure. Ensuite je voudrais le passer dans une liste chainée, à partir de là je coince :(


Message édité par silver53000 le 26-02-2008 à 21:03:27
n°1693099
bjone
Insert booze to continue
Posté le 26-02-2008 à 21:56:26  profilanswer
 

mais sinon tu peux compiler ce que tu écris ? ou tu fais tout à l'aveugle ? c'est censé être une solution compilable telle que ou un bootleg de patricia kaas ? (je blagouille hein panique pas)
 
bon:
d'un point de vue design (heu heu): si c'est pour avoir liste triée, tu peux faire une liste chainée simple. (enfin bon si on t'impose une liste doublement chainée)
 
donc un "contact *suivant" par entrée et pas de précédent. et un "contact *premier" en local au main de préférence (et pas global, enfin là je sais pas trop ce que tu faisais).
 
quand tu as lu avec succès une entrée que tu as stocké dans un maillon alloué, tu te balade du premier au dernier maillon, en l'insérant devant si il est plus petit.
 
donc je veux voir:
- une fonction qui alloue et initialise un maillon
- une fonction qui compare deux maillon pour les trier
- un main qui utilise la première fonction, tente de la renseigner, libère le maillon si le renseignement échoue ou qui le passe à une fonction d'insertion triée dans la liste (et qui donc utilise la fonction de comparaison de maillon).


Message édité par bjone le 26-02-2008 à 21:57:00
n°1693121
silver5300​0
Posté le 26-02-2008 à 23:00:15  profilanswer
 

Code :
  1. typedef struct contact_liste { // on définit la structure qui contiendra les infos du contact
  2. char nom[30];
  3. char prenom[30];
  4. int numero[30];
  5. char email[30];
  6. struct contact_liste *suivant;
  7. }contact;
  8. typedef struct Liste_Repere { // on définit la structure pour avoir le contrôle sur la liste chainée contact_liste. On indique le premier élément, le dernier élément et le nombre d'éléments.  
  9.   contact *debut;
  10.   contact *fin;
  11.   int taille;
  12. }Liste;
  13. void initialisation (Liste *liste){ // on initialise la liste chainée. liste est un pointeur de type Liste
  14.   liste->debut = NULL;
  15.   liste->fin = NULL;
  16.   taille = 0;
  17. }
  18. int insertion_dans_liste_vide (Liste * liste, char *NOM, char *PRENOM, int *NUMERO, char *EMAIL){
  19.   contact *nouveau_contact;
  20.   if ((nouveau_contact = (contact *) malloc (sizeof(contact)) == NULL)
  21. {
  22.  printf("Erreur d'allocation mémoire" );
  23.  return -1;
  24.  }
  25.   else
  26. {
  27.  strcpy (nouveau_contact->nom, NOM);
  28.  strcpy (nouveau_contact->prenom, PRENOM);
  29.  strcpy (nouveau_contact->numero, NUMERO);
  30.  strcpy (nouveau_contact->email, EMAIL);
  31.  nouveau_contact->suivant = NULL;
  32.      liste->debut = nouveau_contact;
  33.      liste->fin = nouveau_contact;
  34.  liste->taille++;
  35.   return 0;
  36. }


 
 
Je me suis aidé de commentçamarche.  
Là j'ai définit ma structure avec les contact, une autre structure pour lier les maillons. Au début j'initialise tout à NULL. Mais ensuite je ne comprend pas vraiment à partir des strcpy (je connais cette fonction strcpy, mais je ne comprends pas ce qu'est *NOM etc...)  
Je rappelle que je me suis aidé d'un tuto, j'ai copié mais je n'ai pas saisi réellement ce qu'il fait quand il copie nouveau_contact->nom dans *NOM.
nouveau_contact est censé être rempli de données là? Et il les copie dans quoi?


Message édité par silver53000 le 26-02-2008 à 23:02:16
n°1693993
silver5300​0
Posté le 27-02-2008 à 22:13:59  profilanswer
 

Je crois avoir compris en fait. Quelqu'un peut il me confirmer si ce début est correct svp.  
Par contre il faudra que je remplisse les chainne de caractère NOM, PRENOM NUMERO et EMAIL au préalable. Comment faire pour que le premier contact soit rempli avec ses bonnes coordonées, ne faut il pas incrémenter?
Autre question, je rempli d'abord toute la liste chainée puis je la trie? ou je trie en même temps que je la rempli? (en gros je la rempli dans le bon ordre)

mood
Publicité
Posté le 27-02-2008 à 22:13:59  profilanswer
 

n°1694751
ffomnislas​h
Posté le 28-02-2008 à 22:02:46  profilanswer
 

Quand tu insère en fin de liste, le début ne change pas ! Par contre le precedent dernier elt de la lsite doit pointer sur le nouveau dernier elt.
Ca donne quelque chose du genre
 

Code :
  1. list->fin->suivant = nouveau
  2. list->fin = nouveau

n°1694926
silver5300​0
Posté le 29-02-2008 à 10:25:26  profilanswer
 

oui, ici la fonction insertion_dans_liste_vide ne sert seulement qu'à ajouter le 1er maillon. Pour ajouter à la suite, j'ai fais cette fonction :  
 

Code :
  1. int insertion_fin_liste (Liste * liste, contact * courant, char *NOM, char *PRENOM, int *NUMERO, char *EMAIL){
  2.  
  3.   contact *nouveau_contact;
  4.   if ((nouveau_contact = (contact *) malloc (sizeof (contact))) == NULL)
  5.   {
  6.   printf("Erreur d'allocation mémoire" );
  7.       return -1;
  8.   }
  9.   else
  10.   {
  11.   strcpy (nouveau_contact->nom, NOM);
  12.   strcpy (nouveau_contact->prenom, PRENOM);
  13.   nouveau_contact->numero=NUMERO;
  14.   strcpy (nouveau_contact->email, EMAIL);
  15.   courant->suivant = nouveau_contact;
  16.   nouveau_contact->suivant = NULL;
  17.   liste->fin = nouveau_contact;
  18.   liste->taille++;
  19.   return 0;
  20.   }
  21. }


Message édité par silver53000 le 29-02-2008 à 10:26:51
n°1694929
Taz
bisounours-codeur
Posté le 29-02-2008 à 10:31:48  profilanswer
 

strcpy (nouveau_contact->nom, NOM);
 
badaboum ! utilise strncpy + chaine[taille - 1] = '\0', voire strlcpy si tu as.

n°1695319
silver5300​0
Posté le 29-02-2008 à 19:02:04  profilanswer
 

ça ne va pas m'apporter grand chose à ce que j'ai pu lire sur strncpy

n°1695914
silver5300​0
Posté le 02-03-2008 à 20:50:56  profilanswer
 

pour trier vous pensez que je part dans la bonne direction?
 

Code :
  1. void tri(Contact *tete)
  2. {
  3. Contact actuel = *tete;
  4. Contact precedent = actuel->suivant;
  5. Contact tmp = NULL;
  6. printf("actuel : %d\n",actuel-> valeur);
  7. printf("precedent : %d\n",precedent-> valeur);
  8.        
  9. while(precedent != NULL)
  10. {   
  11. if (strcmp(actuel->nom, precedent->nom)>0)
  12.       {                                           
  13.         tmp = precedent;
  14.  precedent = actuel; 
  15.  actuel  = tmp ;                 
  16.       }
  17.            
  18.            
  19. actuel=actuel->suivant;
  20. printf("actuel : %d\n",actuel-> valeur);
  21. printf("precedent : %d\n",precedent-> valeur);
  22.                
  23. }


Message édité par silver53000 le 02-03-2008 à 20:51:42
n°1696299
Taz
bisounours-codeur
Posté le 03-03-2008 à 14:48:02  profilanswer
 

silver53000 a écrit :

ça ne va pas m'apporter grand chose à ce que j'ai pu lire sur strncpy


Faire un programme correct ?


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Liste doublement chainée

 

Sujets relatifs
Shoot de mailing listeTaille maximale d'une liste en mémoire (std::list de la STL)
[VBS] AD Créer liste distrib + adresse mailProblème de chargement de donnée dans une liste
Recherche : une liste de noms, prénoms, coordonnées, etc. facticesBug FireFox liste deroulante ?
fonction récursive et liste doublement chainée[Resolu] Transformation d'un fichier en liste doublement chainée
Copie d'une liste doublement chainéeListe doublement chainée
Plus de sujets relatifs à : Liste doublement chainée


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR