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

  FORUM HardWare.fr
  Programmation
  C

  [C] Structure de données à utiliser pour le parcours de dossier

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] Structure de données à utiliser pour le parcours de dossier

n°2033681
Ydalb
In Crêpes n' Cidre I Trust!
Posté le 02-11-2010 à 19:25:55  profilanswer
 

Bonjour à tous.
 
J'ai un programme à faire qui à pour but de parcourir un répertoire et ses sous-répertoires, pour ensuite afficher divers résultats (Nombre de fichiers par utilisateur, leur taille totale cumulées, etc).
 
Je suis en train de réfléchir à la structure de données à utiliser, mais je n'arrive pas à voir comment je pourrais stocker toutes ses informations.
 
J'aimerais procéder ainsi :
- Parcours de tous les fichiers (dossier et sous-dossiers)
- A chaque fichier, je stock l'utilisateur (l'owner), la taille du fichier et le nom du fichier bien sûr
- Je parse le résultat suivant ce qui m'est demander
 
Pour la structure à utiliser, j'étais parti sur une liste par dossier, seulement j'ai un problème :  
- Je vais parcourir le premier dossier, créer une liste comprenant un nombre de noeuds égal au nombre de fichier dans le dossier. Quid des sous-dossiers ? Il me faudrait alors une liste de liste. Mais quid des sous-sous-dossiers ?
 
Je sais pas si vous voyez mon soucis, mais je ne vois pas trop quelle genre de structure 'dynamique' adopter pour un tel projet ...
 
Merci par avance pour vos réponses.
 :hello:  


---------------
:o
mood
Publicité
Posté le 02-11-2010 à 19:25:55  profilanswer
 

n°2033686
olivthill
Posté le 02-11-2010 à 20:21:05  profilanswer
 

Peut-être qu'il serait plus simple d'afficher les résultats au fur et à mesure plutôt que de les stocker.
 
Sinon, la structure est celle d'une arborescence, c'est-à-dire :

Code :
  1. struct _node {
  2.   char name[256]; // Nom du dossier ou du fichier, sans le chemin
  3.   char type; // Dossier ou fichier
  4.   struct _node *parent_node; // pointeur vers le noeud père (ou on pourrait faire un pointeur vers le fils)
  5.   struct _node *next_node; // pointeur vers le noeud suivant au même niveau
  6. }


n°2033710
h3bus
Troll Inside
Posté le 03-11-2010 à 00:23:34  profilanswer
 

Je rajouterais un pointeur child_node, sur le premier élément fils dans le cas d'un répertoire.


---------------
sheep++
n°2033711
Ydalb
In Crêpes n' Cidre I Trust!
Posté le 03-11-2010 à 01:10:06  profilanswer
 

Merci pour vos réponses.

 

J'ai donc utilisé ta structure de données (Tree ?) en rajoutant un pointeur vers le premier élément fils.

 
Code :
  1. typedef struct Leaf
  2. {
  3. struct File *file;
  4. struct Leaf *parent;  // pointeur vers le noeud père
  5. struct Leaf *next;  // pointeur vers le noeud suivant au même niveau
  6. struct Leaf *child; // pointeur vers le fils
  7. } Leaf;
  8. typedef struct Tree
  9. {
  10. Leaf *first;
  11. } Tree;
 

Ma structure File est toute simple :

 
Code :
  1. typedef struct File
  2. {
  3. char *name;
  4. char *owner;
  5. int type;   // 0: dossier, 1: fichier régulier
  6. long long size;
  7. } File;
 


J'ai créé une méthode d'insertion qui va bien :

 
Code :
  1. void addLeaf (Tree *tree, Leaf *parent, Leaf *child)
  2. {
  3. child->child = NULL; // Dans tous les cas, le node qu'on ajoute n'a pas de fils ni de suivant
  4. child->next = NULL;
  5. if (parent == NULL) // Premier élément du Tree
  6. {
  7.  tree->first = child;
  8.  child->parent = NULL;
  9. }
  10. else if (parent->child == NULL) // On ajoute un fils à un parent qui n'a aucun fils
  11. {
  12.  parent->child = child;
  13.  child->parent = parent;
  14. }
  15. else // Le parent a au moins un fils, on ajoute 'child' a la suite
  16. {
  17.  Leaf *current = parent->child;
  18.  Leaf *prev = parent->child;
  19.  while (current != NULL)
  20.  {
  21.   prev = current;
  22.   current = current->next;
  23.  }
  24.  prev->next = child;
  25.  child->parent = parent;
  26. }
  27. }
  28. void addFile (Tree *tree, Leaf *parent, File f) // Méthode qui fait appel à addLeaf ensuite
  29. {
  30. File *file;
  31. file = malloc (sizeof (File));
  32. (*file) = f;
  33. Leaf *child;
  34. child = malloc (sizeof (Leaf));
  35. child->file = file;
  36. addLeaf (tree, parent, child);
  37. }
 


Maintenant j'essaie de parcourir mon arbre. Un parcours en profondeur me suffirait. Après diverses recherches, il semblerait qu'une fonction récursive soit nécessaire. Voici ce à quoi j'arrive :

 
Code :
  1. void displayTree (Tree *tree)
  2. {
  3. if (tree == NULL)
  4. {
  5.  printf("The tree is empty\n" );
  6. }
  7. else
  8. {
  9.  displayChildren (tree->first, 0); // Niveau 0
  10. }
  11. }
  12. void displayChildren (Leaf *leaf, int depth)
  13. {
  14. int i;
  15. for (i=0; i<depth; i++)
  16. {
  17.  printf("\t" ); // Pour indenter l'affichage
  18.  leaf = leaf->child; // On récupère le fils suivant le niveau de profondeur auquel on est arrivé
  19. }
  20. displayFile (*(leaf->file));
  21. while (leaf->next != NULL) // Tant qu'on a un suivant
  22. {
  23.  displayChildren (leaf->next, depth+1);
  24.  leaf = leaf->next;
  25. }
  26. }
 

Bien entendu, ça ne m'affiche pas tout, et je vois pourquoi :
- 1er appel à displayChildren avec le premier noeud, il l'affiche. Ensuite il fait appel au next (des fois qu'il y en aurait), et comme il n'y en a pas, il s'arrête. Or mon premier noeud à des fils, et ces derniers sont ignorés ...

 

Je suis mal parti ?


Message édité par Ydalb le 03-11-2010 à 01:11:06

---------------
:o
n°2033730
olivthill
Posté le 03-11-2010 à 09:37:06  profilanswer
 

Je n'ai pas regardé dans le détail, je laisse cela aux bon spécialistes du C de ce forum.
 
Juste quelques remarques sur la nomenclature :

Code :
  1. typedef struct Tree
  2. {
  3. Leaf *first;
  4. } Tree;

Il ne faut pas nommer de la même manière la structure (le premier Tree) et l'espace alloué pour la structure (le dernier Tree). Une convention assez répandue est de nommer la structure en la faisant commencer par un tiret de soulignement, ce qui donnerait :

Code :
  1. typedef struct _Tree
  2. {
  3. Leaf *first;
  4. } Tree;

En plus, il y a une confusion à cause du typedef.
Pour infos, le typedef n'est pas obligatoire, mais les profs l'aiment beaucoup. Quand on l'utilise, une convention assez répandue est de donner un nom tout en majuscules.
Si on utilise un typedef, alors, il dvient inutile de répeter le mot struct. Gagner ces 6 lettres est un avantage (pour certains (personnellement, je n'utilise japmais typedef car je trouve que cela rend le code moins lisible en cachant ce mot struct, mais c'est un débat de trolls)).

Citation :

Leaf *leaf ... File *file;

Il vaut mieux éviter d'avoir des noms qui se ressemblent trop, car on a vite fait d'oublier la majuscule ou la minuscule.


Message édité par olivthill le 03-11-2010 à 09:41:59
n°2033783
Ydalb
In Crêpes n' Cidre I Trust!
Posté le 03-11-2010 à 12:39:41  profilanswer
 

Merci pour tes remarques, mais j'ai toujours eu l'habitude (grâce / à cause des profs ;)) d'utiliser typedef.
 
pour les noms de variables, je me sers de la règles : commence par une majuscule, c'est un type, commence par une minuscule, c'est une variable, et ça se passe bien.
 
Reste plus qu'à voir pour le parcours de l'arbre :D


---------------
:o
n°2033804
breizhbugs
Posté le 03-11-2010 à 14:46:11  profilanswer
 

Je verrais plutot ton fonction displayChildren comme ca (non testée!):

Code :
  1. void displayChildren (Leaf *leaf, int depth)
  2. {
  3.          int i;
  4.         if (leaf != NULL)
  5.        {
  6.      for (i=0; i<depth ; i++)
  7.     {
  8.  printf("\t" ); // Pour indenter l'affichage
  9.     }
  10.             displayChildren(Leaf->child, depth+1); // on affiche d'abord les fils (donc a une profondeur de plus)
  11.             displayChildren (leaf->next, depth); // Les nœuds "frères" sont au même niveau!, on n'affiche que le premier (qui lui affichera a son tour son premier, etc)
  12.      displayFile (*(leaf->file)); // on affiche les fichiers du répertoire courant.
  13.         }
  14. }


Message édité par breizhbugs le 03-11-2010 à 14:47:45
n°2033808
theshockwa​ve
I work at a firm named Koslow
Posté le 03-11-2010 à 14:55:53  profilanswer
 

pour faire ce genre de traitements, j'aurais intuitivement envie d'éviter de stocker des infos sur chaque fichier en mémoire vu que le nombre de fichiers à traiter va probablement être conséquent.
 
Je te conseillerais plutôt de partir plus dans une optique de requête et appliquer cette requête sur chaque fichier / dossier en faisant une passe sur ton disque.
 
La requête sachant elle-même si elle doit compter des fichiers, calculer une taille ou autre. Ca a un autre avantage, c'est que tu pourras faire des requêtes composites assez aisément avec un système de ce genre.
 


---------------
last.fm

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

  [C] Structure de données à utiliser pour le parcours de dossier

 

Sujets relatifs
Transfert de données DB2/400 vers Oracle[C] Récuper l'utilisateur à partir de l'uid
Importer données d'un autre site sur son site webStructure en c sur un tableau de chaine de caractere
[C#] Erreur lors de l'ouverture d'un fichierlangage C, message d'erreur
Ouvrir fenêtre Glut depuis fenêtre C#[C] tableau dynamique 2 dimension
Comparaison/Test de "structure" XML[Apprentissage] Passage de Java à C#
Plus de sujets relatifs à : [C] Structure de données à utiliser pour le parcours de dossier


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