listes chainées

listes chainées - C - Programmation

Marsh Posté le 26-12-2013 à 20:19:39    

bonjour à tous,
svp voici mon code qui crée des repertoires:un repertoire doit contenir au max deux sous-repertoires et des fichiers l'affichage ne marche pas .je vois pas ou est le probleme :
 

Code :
  1. typedef struct {int jour;int mois;int annee;}date;
  2. typedef struct {char nomfich[15];long taille; date datecreation;}infofich;
  3. typedef struct elt{infofich info; struct elt *svt;} fichier;
  4. typedef struct eltr{char nom_rep[15]; char sous_rep1[15]; char sous_rep2[15]; struct elt *lien;}rep;
  5. typedef struct eltl{rep info; struct eltl *next;} liste;
  6. /*creation d'une liste de fichier */
  7. fichier *creation(int m)
  8. { fichier *q,*T=NULL;    int j=0;
  9. for(j=0;j<m;j++)
  10. { q=(fichier *)malloc(sizeof(fichier));
  11. printf("entrez le contenue du fichier: nom,taille \n" );
  12. scanf("%s %ld",q->info.nomfich,&q->info.taille);
  13. printf("entrez la date de creation du fichier:jj,mm,AAAA\n" );
  14. scanf("%d %d %d ",&q->info.datecreation.jour,&q->info.datecreation.mois,&q->info.datecreation.annee);
  15. q->svt=T;    T=q;}
  16. return(T);}
  17. /*creation d'une liste de repertoire avec double chainage un avec le suivant et l'autre avec la liste de fichier*/
  18. liste *creat_rep(int n)
  19. { liste *tete=NULL,*p; int i,m;
  20. for (i=0;i<n;i++)
  21. { p=(liste *)malloc(sizeof(liste));
  22. printf("entrez le nom du repertoire et des sous repertoires \n" );
  23. scanf("%s %s %s",p->info.nom_rep,p->info.sous_rep1,p->info.sous_rep2);
  24. p->next=tete; tete=p;
  25. printf("entrez le nombre de fichier dans ce repertoire \n" );
  26. scanf("%d",&m);
  27. p->info.lien=creation(m); }
  28. return(tete); }
  29. /*afficher un repertoire donné*/
  30. void affichage(liste *tete,char *ch)
  31. { liste *p,*r; fichier *q;
  32. for(p=tete;p!=NULL &&(strcmp(p->info.nom_rep,ch)!=0) ;r=p,p=p->next)
  33. if (p==NULL) printf("ce repertoire n'existe pas \n" );
  34. printf("%s %s %s", (r->next)->info.nom_rep, (r->next)->info.sous_rep1, (r->next)->info.sous_rep2);
  35. for(q=(r->next)->info.lien;q!=NULL;q=q->svt)
  36. printf("%s %ld la date de creation est: %d %d %d",q->info.nomfich, q->info.taille, q->info.datecreation.jour, q->info.datecreation.mois, q->info.datecreation.annee);
  37. }
  38. int main()
  39. { liste *tete=NULL,*p; fichier *q,*r; int n; char ch[15];
  40. printf("combien de repertoire voulez-vous crée ?? \n" );
  41. scanf("%d",&n);
  42. tete=creat_rep(n);
  43. printf("entrez le nom du repertoire que vous voulez afficher \n" );
  44. scanf("%s",ch);
  45. affichage(tete,ch);
  46. return 0;}

Reply

Marsh Posté le 26-12-2013 à 20:19:39   

Reply

Marsh Posté le 27-12-2013 à 17:38:01    

Bonjour,

 

D'abord je pense qu'il va falloir apprendre à indenter le code parce que là
c'est difficile à lire.

 

À mon avis le gros problème vient de l'utilisation de scanf. Scanf est une
fonction qui sert à lire des données formattées et n'est donc pas applicable
pour une saisie au clavier puisqu'un utilisateur ne respecte jamais le format
voulu. Sa "simplicité" apparente fait que tout le monde l'enseigne et c'est
ainsi qu'on prend de mauvaises habitudes.

 

Pour la remplacer on utilise fgets:
char *fgets(char *s, int size, FILE *stream);

 

Cette fonction permet de récupérer une chaîne de caractères. Pour récupérer un
nombre il faut la convertir avec strtol:
long int strtol(const char *nptr, char **endptr, int base);

 

C'est un peu plus compliqué je l'admet mais cela évite de faire des erreurs. La
fonction création utilisera donc les fonctions ainsi:

 
Code :
  1. char temp[15];
  2. q=(fichier *)malloc(sizeof(fichier));
  3. printf("Entrez le nom du fichier: " );
  4. fgets(q->info.nomfich, sizeof(q->info.nomfich), stdin); //récupération de la saisie
  5. q->info.nomfich[strlen(q->info.nomfich) - 1 ] = 0; //Suppression du caractère \n à la fin de la chaîne voir le man de fgets
  6.    
  7. printf("Entrez la taille du fichier: " );
  8. fgets(temp, sizeof(temp), stdin); //Récupération de la saisie
  9. q->info.taille = strtol(temp, NULL, 0); //Conversion en un nombre
  10. printf("fichier: %s, taille: %d\n", q->info.nomfich, q->info.taille); //affichage pour vérifier, à supprimer
 

En remplaçant tous les scanf, cela devrait déjà plus ressembler à quelque chose.

 

La fonction affichage ne peut pas fonctionner si le répertoire affiché est le
premier de la liste car la variable r n'est pas initialisée (on quitte la boucle
avant l'affectation). Il manquait aussi un ; à la fin de la boucle for pour la
faire tourner "dans le vide".

Code :
  1. void affichage(liste *tete,char *ch)
  2. {
  3.     liste *p; fichier *q;
  4.     for(p=tete; p!=NULL && (strcmp(p->info.nom_rep,ch)!=0); p=p->next);
  5.     if (p==NULL)
  6.         printf("ce repertoire n'existe pas \n" );
  7.     else
  8.     {
  9.         printf("%s %s %s\n", p->info.nom_rep,
  10.                p->info.sous_rep1,
  11.                p->info.sous_rep2);
  12.         for(q=p->info.lien; q!=NULL; q=q->svt)
  13.             printf("%s %ld la date de creation est: %d %d %d\n",q->info.nomfich,
  14.                    q->info.taille, q->info.datecreation.jour,
  15.                    q->info.datecreation.mois, q->info.datecreation.annee);
  16.     }
  17. }
 

Attention de ne pas oublier les \n à la fin d'un printf. C'est plus pratique
pour lire mais cela permet aussi de s'assurer que le terminal affiche bien ce
que l'on veut, sinon il risque de garder les caractères en buffer en attendant
une hypothétique suite.

 


Edit: en validant mon message, toutes les tabulations sont passées à la
trappe donc le pb vient peut-être du forum et non de l'indentation.


Message édité par ptitchep le 27-12-2013 à 17:45:59

---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 28-12-2013 à 19:01:10    

merci pour votre aide

Reply

Sujets relatifs:

Leave a Replay

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