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

  FORUM HardWare.fr
  Programmation
  C

  [C] parcourir une arborescence de repertoire

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] parcourir une arborescence de repertoire

n°1313516
cflorian91​1
Posté le 25-02-2006 à 15:37:09  profilanswer
 

Bonjour, voila je dispose d'un repertoire MP3 qui contient un repertoire rock et classique. Je voudrais faire un programme en C qui affiche tous les fichiers,répertoires et sous répertoires du repertoire MP3. J'ai réalisé un programme mais le probleme c'est qu'il m'affiche que rock et classique et il n'affiche pas ce qu'il y a dans rock et classique. Pouvez vous m'aider svp.
Voici mon code:
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
 
//Prototypes
DIR *opendir (const char *filename);
struct dirent *readdir (DIR * dirp);
int closedir (DIR * dirp);
 
//ACTION SUR FICHIER ET REPERTOIRE
 
//Action sur un repertoire
void action_dir (const char *dir)
    {printf("%s/\n", dir);}
 
//action sur un rep avt parcour de son contenu
void action_dir_pre (const char *root, const char *dir)
    {printf("\n-> %s/%s/\n", root, dir);}
 
//action sur un re apres parcour de son contenu
void action_dir_post (const char *root, const char *dir)
    {}
 
//action sur un fichier
void action_file (const char *file)
    {printf("%s\n", file);}
 
//DEFINITION D'UNE LISTE CHAINEE SIMPLE
typedef struct slist_t
   {
     char *name;
     int is_dir;
     struct slist_t *next;
   }slist_t;
 
//PARCOURS RECURSIF DES REPERTOIRES
int recursive_dir (char *root, char *MP3)
   {
     slist_t *names = NULL;
     slist_t *sl;
 
     DIR *FD;
     struct dirent *f;
     int cwdlen = 32;
     char *cwd;
     char *new_root;
 
     if (NULL ==(cwd=malloc(cwdlen* sizeof *cwd)))
       {
         fprintf(stderr, "probleme avec malloc\n" );
         exit(EXIT_FAILURE);
       }
 
     //Concatenation new_root="root/MP3"
     if (root)
       {
         int rootlen = strlen (root);
         int dirnamelen = strlen ("MP3" );
         if (NULL == (new_root = malloc((rootlen + dirnamelen +2) * sizeof *new_root)))
           {
             fprintf (stderr, "probleme avec malloc\n" );
             exit (EXIT_FAILURE);
           }
         memcpy (new_root, root, rootlen);
         new_root[rootlen] = '/';
         memcpy (new_root + rootlen + 1, MP3, dirnamelen);
         new_root[rootlen + dirnamelen + 1] = '\0';
       }
     else
         new_root = strdup ("MP3" );
 
     //obtention du repertoire courant
     while (NULL == (cwd = getcwd (cwd, cwdlen)))
        {
          if (ERANGE != errno)
            {
              fprintf (stderr, "probleme avec getcwd (errno= '%s')\n",strerror (errno));
              exit (EXIT_FAILURE);
            }
          cwdlen += 32;
          cwd = realloc (cwd, cwdlen * sizeof *cwd);
        }
     chdir ("MP3" );
 
     //Remplissage de la liste avec les noms des fichiers du rep courant
     if (NULL == (FD = opendir ("." )))
       {
         fprintf (stderr, "opendir() impossible\n" );
         return (-1);
       }
     sl = names;
     while ((f = readdir (FD)))
       {
         struct stat st;
         slist_t *n;
         if (!strcmp (f->d_name, "." ))
             continue;
         if (!strcmp (f->d_name, ".." ))
             continue;
         if (stat (f->d_name, &st))
             continue;
         if (NULL == (n = malloc (sizeof *n)))
            {
              fprintf (stderr, "Plus assez de memoire\n" );
              exit (EXIT_FAILURE);
            }
         n->name = strdup (f->d_name);
         if (S_ISDIR (st.st_mode))
            n->is_dir = 1;
         else
            n->is_dir = 0;
         n->next = NULL;
         if (sl)
           {
             sl->next = n;
             sl = n;
           }
         else
           {
             names = n;
             sl = n;
           }
        }
      closedir (FD);
 
      //parcourt les fichiers et repertoire pour action
      for (sl= names; sl; sl = sl->next)
         {
           if (sl->is_dir)
             action_dir (sl->name);
           else
             action_file (sl->name);
         }
 
      //parcourt les fichiers et rep pr actoin avt traitement recursif et apres traitement recursif
/*      for (sl = names; sl; sl = sl->next)
         {
           if (sl->is_dir)
              {
                action_dir_pre (new_root, sl->name);
                recursive_dir (new_root, sl->name);
                action_dir_post (new_root, sl->name);
              }
         }
*/
      //Nettoyage
      free (new_root);
      while (names)
        {
          slist_t *prev;
          free (names->name);
          prev = names;
          names = names->next;
          free (prev);
        }
      chdir (cwd);
      free (cwd);
      return(0);
   }
 
int main (int argc, char **argv)
    {
     if (argc >= 1)
          recursive_dir (NULL, argv[1]);
      exit (0);
    }

mood
Publicité
Posté le 25-02-2006 à 15:37:09  profilanswer
 

n°1313533
Sve@r
Posté le 25-02-2006 à 16:55:27  profilanswer
 

Bon, je vais être sincère, je n'ai pas envie de tout dérouler l'algo à la main pour voir où est le bug probablement minuscule car apparemment, tout à l'air correct. Evidemment avec la masse de commentaires que tu y as mis, c'est pas non plus très facile de comprendre ce que tu cherches à faire. Mais j'ai quand-même quelques remaques...
 
1) il me semble que ta fonction de traitement reçoit un répertoire en paramètre, se déplace dedans avec "chdir" pour lire son contenu (c'est pas facile de tout comprendre) et génère pour chaque sous répertoire un nom contenant le nom courant concaténé au nom du sous répertoire. A mon avis, si j'ai bien compris ce que tu fais, c'est là qu'est le bug. Si tu as un répertoire "MP3" contenant un sous-répertoire "toto", ben quand tu es dans "MP3" ce que tu vois se nomme "toto" et non "MP3/toto". Donc soit tu ne fais aucun "chdir" (c'est d'ailleurs ce que je te conseillerais car je trouve ce déplacement inutile), soit tu ne concatènes pas le nom du sous-répertoire au nom du répertoire dans lequel tu te trouves.
Donc voici l'algo que je te conseillerais pour ta fonction qui reçoit un répertoire en paramètre

ouvrir répertoire
pour chaque fichier, faire
    si "." ou ".." on saute
    si répertoire, alors
        concaténer nom fichier au nom du répertoire courant
        appeler la fonction pour le nom ainsi créé
    fin  si
    si fichier alors
        afficher le nom
    fin si
fin pour
fermer répertoire


 
2) dans des traitements de chaîne, vaut mieux utiliser "strcpy" et/ou "strcat" (qui gèrent le '\0') plutôt que "memcpy". Et il est plus judicieux d'utiliser "sprintf" pour mettre dans une chaîne plein de trucs plutôt que tous ces "memcpy".
Ainsi, toute cette structure :

 
memcpy (new_root, root, rootlen);  
new_root[rootlen] = '/';  
memcpy (new_root + rootlen + 1, MP3, dirnamelen);  
new_root[rootlen + dirnamelen + 1] = '\0';  

peut être avantageusement remplacé par :

sprintf(new_root, "%s/%s", root, MP3);


 


Message édité par Sve@r le 25-02-2006 à 17:00:54

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.

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

  [C] parcourir une arborescence de repertoire

 

Sujets relatifs
Impossible d'effacer un répertoire créé avec PHPListe des fichiers d'un répertoire sous LabWindows/CVI
Repertoire de l'application + ShellExecutegénérer automatiquement un répertoire
Copie de répertoire avec if avec un serveur sous Windows 2000 ServeurDéfinir un répertoire de sortie
lire un repertoirestat -> savoir si c'est un repertoire
Listing répertoire de MP3 et lecture des tags de ces fichiers[VC++] Repertoire
Plus de sujets relatifs à : [C] parcourir une arborescence de repertoire


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