liste chainée et traitemenbts de fichier

liste chainée et traitemenbts de fichier - C - Programmation

Marsh Posté le 10-01-2005 à 09:15:07    

Bonjour je suis en train de faire un projet de gestion de carnet d'adresse
chaques contact doit etre stockée dans des fiuchier qui sont des groupes de contacts, j'utilise pour cela des listes chainées pour entrer chaques contacts dans chaques groupe ,hors j'ai un petit probleme ,
Dans CE code :
 
 
//Fonction qui permet d'ouvrir un fichier
 
int Ouvrir_fichier (char nom_du_fichier[] , TFiche_contact * une_fiche)
{
 
 FILE *fp;   // Pointeur du fichier courrant      
 char test[15];
 int c;
 TContact* nouvelle_fiche;
 
 strcat(nom_du_fichier ,".eca" );     // Ajoute l'extention au nom de la fiche
 fp = (fopen(nom_du_fichier ,"a+" ));
   
 if( fp== NULL)          // Retourne NULL si existe pas
 {
  printf("\a\nFichier introuvable\n" );
  return 0;
 }
 
 fgets (test,6,fp);
 
 if (strcmp(test,"eca 1" ))
    {
        printf("\a\nFichier non valide" );
        fclose(fp);
        return 0;
    }
 
 
 while (!feof(fp))
 {
  nouvelle_fiche=((TContact*)malloc(sizeof(TContact)));  
  nouvelle_fiche->ptsuivant= NULL;
 
        fscanf(fp,"%s %s %s %i %s %s %s %s ",
   nouvelle_fiche->Nom,
   nouvelle_fiche->Prenom,
   nouvelle_fiche->Adresse,
   nouvelle_fiche->Age,
   nouvelle_fiche->Telephone,
   nouvelle_fiche->Fonction,
   nouvelle_fiche->Mail,
   nouvelle_fiche->Date_de_naissance);  
   
   Ajouter_contact_dans_fiche[nouvelle_fiche,une_fiche);
 
 }
 
 fclose (fp);
 
return 1;
 
}
 
Mon but est de créer un maillon puis de l'initialiser dans la boucle while avec les lectures de fscanf et en suite de le lier avec la fonction Ajouter_contact_dans_fiche ,mais a ce moment du code j'ai une expecp. acces violation au niveau de ma fonction d'ajout de maillon  
 
Quelqu'un pourrait il m'aider a comprendre le principe des listes chainée ,j'ai bien trouvé quelques trucs sur le net mais cje comprend touojours pas ...
lerci d'avance

Reply

Marsh Posté le 10-01-2005 à 09:15:07   

Reply

Marsh Posté le 10-01-2005 à 10:24:38    

Si je comprend bien, une_fiche est la derniere fiche rentrée et Ajouter_contact_dans_fiche permet de mettre une_fiche->ptsuivant = nouvelle_fiche
 
C'est bien ca ?
 
Je ne vois pas trop l'erreur (mais ca fait longtemps que je n'ai pas utilisé les listes chainées.
Le concept est que chaque élément possède l'adresse de son suivant (et à la limite de son précédent pour des questions de performances).
Ainsi, en ayant seulement l'adresse de ton premier élément, tu peux naviguer dans ta sorte de liste d'éléments.
 
Meme si c'est assez pratique, pourquoi ne pas utiliser des tableaux de structures classiques ?
C'est à dire définir une structure de type Struct_fiche contenant tous champs Nom, Prenom, ... et ensuite déclarer un tableau de cette structure Struct_fiche *Mon_repertoire
 
Les listes chainées te sont imposées ?
 
Désolé de pas avoir pu t'aider beaucoup plus ...

Reply

Marsh Posté le 10-01-2005 à 10:57:57    

Déjà ton code C comporte pas mal de pratiques dangeureuses (malloc etc).
 
Ensuite, d'un point de vue algorithmique, tu ne fait aucun chainage quand tu ajoute un maillon...
Pense à garder la trace du maillon précédent sinon ton biniou ne risque pas de marcher.
;)

Reply

Marsh Posté le 10-01-2005 à 12:50:12    

comme dit pains-aux-raisins vaut mieux utiliser calloc car lui initialise les champs a 0 tant dis que malloc ne le fait pas systematiquement enfin pour plus de detail regarde le man


---------------
  ____
Reply

Marsh Posté le 10-01-2005 à 13:10:35    

Pour les utilisateurs de linux, il existe dans la glib les GList et GSList qui ont étés conçus pour gérer les listes.

Reply

Marsh Posté le 11-01-2005 à 09:39:59    

si dans la fonction
 Ajouter_contact_dans_fiche[nouvelle_fiche,une_fiche);  
j'ajoute un maillon (une contact) dans une liste (une fiche) mais c'est la que ca plante
 

Code :
  1. /  *************** Gestion des contacts ***************
  2. //Fonction qui trouve le dernier contact
  3. TContact * Trouver_dernier_Contact (TFiche_contact * une_fiche)
  4. {
  5. TContact *  pt_test=une_fiche->pt_tete;  // pointeur qui va tester le maillon
  6. if (pt_test!=NULL)        // renvoie NULL si vide
  7. // return NULL;
  8. {
  9. while (pt_test->ptsuivant!=NULL)
  10.  pt_test=pt_test->ptsuivant;
  11. }
  12. return pt_test;
  13. }
  14. //Fonction qui trouve l'avant dernier contact
  15. TContact* Trouver_avant_dernier_Contact (TFiche_contact * une_fiche)
  16. {
  17. TContact *  pt_test;      // pointeur qui va parcourir la fiche
  18. TContact *  pt_test_qui_suit;    // pointeur qui suit derriere
  19. pt_test=une_fiche->pt_tete;
  20. pt_test_qui_suit=pt_test;
  21. if (pt_test==NULL)        // renvoie NULL si vide
  22.  return NULL;
  23. while (pt_test->ptsuivant!=NULL)
  24.  {
  25.   pt_test_qui_suit=pt_test;
  26.   pt_test=pt_test->ptsuivant;
  27.  }
  28. return pt_test_qui_suit;
  29. }
  30. void Ajouter_contact_dans_fiche(TContact * nvelle_fiche_a_ajouter,TFiche_contact * une_fiche )  //Fonction qui permet d'ajouter un contact
  31. {
  32. TContact * dernier_contact_de_fiche;
  33.    
  34. /*dernier_contact_de_fiche=Trouver_dernier_Contact (une_fiche);
  35. dernier_contact_de_fiche->ptsuivant=nvelle_fiche_a_ajouter;
  36. nvelle_fiche_a_ajouter->ptsuivant=NULL;*/
  37. if (une_fiche->pt_tete==NULL)
  38.  une_fiche->pt_tete=nvelle_fiche_a_ajouter;
  39. else
  40.  {
  41.  dernier_contact_de_fiche=Trouver_dernier_Contact (une_fiche);
  42.  dernier_contact_de_fiche->ptsuivant=nvelle_fiche_a_ajouter;
  43.  }
  44. }


Message édité par bleuerouge le 11-01-2005 à 09:41:51
Reply

Marsh Posté le 11-01-2005 à 10:42:37    

Non, non et non...
Avec ta manière de procéder, tu perds une grande partie de l'avantage des listes chaînées, à savoir un temps d'insertion en temps constant O(1). Ici, ton temps d'insertion est en O(n) :/ à cause de ta recherche systématique sur le dernier élément.
 
Pour ajouter un élément dans une liste simplement chaînée tu a le choix de l'ajouter soit en tete, soit en queue.
Le plus simple est l'ajout en tete.
 
Tout d'abord il faut avoir la structure adéquate. Déclarer les types Maillon et ListeSimple :

Code :
  1. typedef struct {
  2.    int valeur;
  3. } TContact;
  4. typedef struct _Maillon {
  5.    TContact contact;
  6.    struct _Maillon* suivant;
  7. } Maillon;
  8. typedef struct {
  9.    Maillon* tete;
  10.    Maillon* queue;
  11. }  ListeSimple;


 
Ensuite pour ajouter un élément en tete l'algo est le suivant :

Code :
  1. ListeSimple* ajout_en_tete(TContact* contact, ListeSimple* liste) {
  2.    Maillon* newmaillon = NULL;
  3.    if ((newmaillon = (Maillon *)malloc(sizeof(Maillon))) != NULL) {
  4.       newmaillon->contact = *contact;
  5.       newmaillon->suivant = liste->tete;
  6.       liste->tete = newmaillon;
  7.    }
  8.    else { /* faut gérer le manque de mémoire */ }
  9. }


Reply

Marsh Posté le 11-01-2005 à 10:46:18    

Pour l'ajout en queue, l'algo est similaire sauf qu'il faut chainer la queue de la liste avec le nouvel élément, puis définir ce nouvel élément comme queue de liste.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed