Le mercredi 5 mars, Benoit Lion a écrit :
> Je voudrais faire un programme qui parcours tous les fichiers d'un
> répertoire et de ses sous-répertoires. J'ai fait cela dans mes
> lointaines études, mais j'ai oublié. Quelqu'un aurait-il un exemple
> récursif en langage c ?
Un exemple en pseudo code (pseudo C...) :
int crawl(char *directory)
{
int ret;
char *entry;
/* Go to the directory. */
ret = chdir(directory);
if (ret == -1) {
perror(directory);
return -1;
}
/* Scan all the entries. */
foreach (entry in the directory) {
if (is_directory(entry)) {
ret = crawl(entry); /* recursive call */
if (ret == -1) return -1; /* stop everything if error */
}
else do_stuff_with_file(entry);
}
/* Get back. */
chdir("..");
return 0;
}
Pour transformer ça en vrai code :
foreach (entry in the directory) -> man 3 readdir
is_directory(entry) -> man 2 stat
do_stuff_with_file() représente bien-sûr l'action que tu veux faire sur
chaque fichier.
Variations :
- tu supprimes la ligne « stop everything if error » si tu ne veux
pas arrêter la récursion à la première erreur.
- tu remplaces la boucle foreach par deux boucles :
foreach (entry in the directory)
if (is_directory(entry)) crawl(entry);
foreach (entry in the directory)
if (!is_directory(entry)) do_stuff_with_file(entry);
si tu veux traiter le contenu des sous-répertoires avant celui de
leurs parents. Tu inverses l'ordre des boucles ci-dessus dans le
cas contraire. Cependant, cela demande de parcourir le répertoire
avec readdir() deux fois (man rewinddir), à moins de garder en
mémoire son contenu.
- tu ne fais pas de chdir, mais alors tu dois construire les chemins
relatifs au répertoire de départ :
foreach (entry in the directory) {
char *path = malloc(strlen(directory) + strlen(entry) + 2);
if (!path) {
perror("malloc");
exit(EXIT_FAILURE); /* ENOMEM: we are doomed */
}
strcat(strcat(strcpy(path, directory), "/"), entry);
if (is_directory(path)) crawl(path);
else do_stuff_with_file(path);
free(path);
}
--
Edgar Bonet Tél : 04 76 88 10 96
Laboratoire Louis Néel -- CNRS Mobile : 06 77 19 79 39
25 av. des Martyrs, BP 166 Fax : 04 76 88 11 91
38042 Grenoble cedex 9, France e-mail : guilde@???