Usa la funzione opendir in C
-
Utilizzare la funzione
opendir
per aprire un flusso di directory -
Utilizzare la funzione
readdir
per ripetere le voci di directory
Questo articolo spiegherà diversi metodi su come utilizzare la funzione opendir
in C.
Utilizzare la funzione opendir
per aprire un flusso di directory
La funzione opendir
fa parte della specifica POSIX ed è definita nel file di intestazione <dirent.h>
. La funzione accetta un singolo argomento del puntatore char
per specificare il nome della directory da aprire. opendir
restituisce la struttura DIR*
o NULL
se si incontra un errore. Il tipo di dati DIR
è implementato per rappresentare il flusso di directory, ma l’utente non deve allocare oggetti del tipo DIR
. Nel seguente codice di esempio, prendiamo il nome della directory dal primo argomento della linea di comando e passiamo il valore alla funzione 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);
}
Utilizzare la funzione readdir
per ripetere le voci di directory
Una volta che il flusso della directory è aperto e abbiamo recuperato la DIR*
valida, possiamo leggere ogni voce contenuta usando la funzione readdir
. Ogni chiamata alla funzione readdir
restituisce un puntatore alla struttura dirent
che rappresenta la voce di directory successiva. Quando viene raggiunta la fine del flusso della directory, readdir
restituisce NULL
. Quindi, abbiamo implementato un semplice cicli while
che stampa ogni voce nel flusso di directory aperto. Abbiamo modificato il codice intorno alle chiamate alle funzioni opendir
e closedir
per verificare la presenza di errori e visualizzare il messaggio corrispondente per il debug. È sempre buona e sicura pratica controllare se le funzioni della libreria sono state restituite correttamente.
#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);
}
In alternativa, possiamo aggiungere alcune istruzioni condizionali per il controllo degli errori per la funzione readdir
perché l’esempio precedente potrebbe produrre un output non chiaro quando il nome della directory non è valido o si è verificato un errore diverso. Il codice seguente restituirà inoltre lo stato raggiunto di fine directory dopo l’iterazione riuscita.
#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