parcourir une arborescence de repertoire [C] - C - Programmation
Marsh Posté le 25-02-2006 à 16:55:27
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 |
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 :
|
peut être avantageusement remplacé par :
sprintf(new_root, "%s/%s", root, MP3); |
Marsh Posté le 25-02-2006 à 15:37:09
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);
}