Utilisez la fonction opendir en C
-
Utilisez la fonction
opendir
pour ouvrir un flux d’annuaire -
Utilisez la fonction
readdir
pour parcourir les entrées du répertoire
Cet article explique plusieurs méthodes d’utilisation de la fonction opendir
en C.
Utilisez la fonction opendir
pour ouvrir un flux d’annuaire
La fonction opendir
fait partie de la spécification POSIX et est définie dans le fichier d’en-tête <dirent.h>
. La fonction prend un seul argument de pointeur char
pour spécifier le nom du répertoire à ouvrir. opendir
renvoie la structure DIR*
ou NULL
si une erreur est rencontrée. Le type de données DIR
est implémenté pour représenter le flux d’annuaire, mais l’utilisateur ne doit pas allouer d’objets de type DIR
. Dans l’exemple de code suivant, nous prenons le nom du répertoire du premier argument de ligne de commande et passons la valeur à la fonction opendir
.
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
DIR *dp;
struct dirent *dirp;
if (argc != 2) {
fprintf(stderr, "Usage: ./program directory_name\n");
exit(EXIT_FAILURE);
}
dp = opendir(argv[1]);
while ((dirp = readdir(dp)) != NULL) printf("%s\n", dirp->d_name);
closedir(dp);
exit(EXIT_SUCCESS);
}
Utilisez la fonction readdir
pour parcourir les entrées du répertoire
Une fois que le flux du répertoire est ouvert et que nous avons récupéré le DIR*
valide, nous pouvons lire chaque entrée en utilisant la fonction readdir
. Chaque appel à la fonction readdir
renvoie un pointeur vers la structure dirent
représentant l’entrée suivante du répertoire. Lorsque la fin du flux du répertoire est atteinte, readdir
renvoie NULL
. Ainsi, nous avons implémenté une simple boucle while
qui imprime chaque entrée dans le flux de répertoire ouvert. Nous avons modifié le code autour des appels de fonction opendir
et closedir
pour vérifier les erreurs et afficher le message correspondant pour le débogage. Il est toujours bon et sûr de vérifier si les fonctions de la bibliothèque ont été renvoyées avec succès.
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
DIR *dp;
struct dirent *dirp;
if (argc != 2) {
fprintf(stderr, "Usage: ./program directory_name\n");
exit(EXIT_FAILURE);
}
errno = 0;
if ((dp = opendir(argv[1])) == NULL) {
switch (errno) {
case EACCES:
printf("Permission denied\n");
break;
case ENOENT:
printf("Directory does not exist\n");
break;
case ENOTDIR:
printf("'%s' is not a directory\n", argv[1]);
break;
}
exit(EXIT_FAILURE);
}
while ((dirp = readdir(dp)) != NULL) printf("%s\n", dirp->d_name);
if (closedir(dp) == -1) perror("closedir");
exit(EXIT_SUCCESS);
}
Alternativement, nous pouvons ajouter des instructions conditionnelles de vérification d’erreur pour la fonction readdir
car l’exemple précédent peut donner une sortie peu claire lorsque le nom du répertoire est invalide ou qu’une erreur différente s’est produite. Le code suivant affichera en outre l’état de fin de répertoire atteint après l’itération réussie.
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
DIR *dp;
struct dirent *dirp;
if (argc != 2) {
fprintf(stderr, "Usage: ./program directory_name\n");
exit(EXIT_FAILURE);
}
errno = 0;
if ((dp = opendir(argv[1])) == NULL) {
switch (errno) {
case EACCES:
printf("Permission denied\n");
break;
case ENOENT:
printf("Directory does not exist\n");
break;
case ENOTDIR:
printf("'%s' is not a directory\n", argv[1]);
break;
}
exit(EXIT_FAILURE);
}
errno = 0;
while ((dirp = readdir(dp)) != NULL) printf("%s\n", dirp->d_name);
if (errno != 0) {
if (errno == EBADF)
printf("Invalid directory stream descriptor\n");
else
perror("readdir");
} else {
printf("End-of-directory reached\n");
}
if (closedir(dp) == -1) perror("closedir");
exit(EXIT_SUCCESS);
}
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook