Verwendung der opendir-Funktion in C
-
Verwenden Sie die Funktion
opendir
, um einen Verzeichnisstrom zu öffnen -
Verwenden Sie die Funktion
readdir
, um über Verzeichniseinträge zu iterieren
In diesem Artikel werden mehrere Methoden zur Verwendung der Funktion opendir
in C erklärt.
Verwenden Sie die Funktion opendir
, um einen Verzeichnisstrom zu öffnen
Die Funktion opendir
ist Teil der POSIX-Spezifikation und ist in der Header-Datei <dirent.h>
definiert. Die Funktion nimmt ein einzelnes char
-Zeigerargument entgegen, um den zu öffnenden Verzeichnisnamen anzugeben. opendir
gibt eine DIR*
-Struktur zurück oder NULL
, wenn ein Fehler auftritt. Der Datentyp DIR
ist implementiert, um einen Verzeichnisstrom darzustellen, aber der Benutzer sollte keine Objekte vom Typ DIR
zuweisen. Im folgenden Beispielcode nehmen wir den Verzeichnisnamen aus dem ersten Befehlszeilenargument und übergeben den Wert an die Funktion 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);
}
Verwenden Sie die Funktion readdir
, um über Verzeichniseinträge zu iterieren
Sobald der Verzeichnisstrom geöffnet ist und wir das gültige DIR*
abgerufen haben, können wir jeden Eintrag darin mit der Funktion readdir
lesen. Jeder Aufruf der Funktion readdir
gibt einen Zeiger auf die Struktur dirent
zurück, die den nächsten Verzeichniseintrag repräsentiert. Wenn das Ende des Verzeichnisstroms erreicht ist, gibt readdir
NULL
zurück. So haben wir eine einfache while
-Schleife implementiert, die jeden Eintrag im geöffneten Verzeichnisstrom ausgibt. Wir haben den Code um die Funktionsaufrufe opendir
und closedir
modifiziert, um auf Fehler zu prüfen und die entsprechende Meldung zur Fehlersuche auszugeben. Es ist immer eine gute und sichere Praxis, zu prüfen, ob die Bibliotheksfunktionen erfolgreich zurückgekehrt sind.
#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);
}
Alternativ können wir einige bedingte Anweisungen zur Fehlerprüfung für die Funktion readdir
hinzufügen, da das vorherige Beispiel möglicherweise eine unklare Ausgabe liefert, wenn der Verzeichnisname ungültig ist oder ein anderer Fehler aufgetreten ist. Der folgende Code gibt nach der erfolgreichen Iteration zusätzlich den Status “Ende des Verzeichnisses erreicht” aus.
#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