Verwendung der opendir-Funktion in C

Jinku Hu 12 Oktober 2023
  1. Verwenden Sie die Funktion opendir, um einen Verzeichnisstrom zu öffnen
  2. Verwenden Sie die Funktion readdir, um über Verzeichniseinträge zu iterieren
Verwendung der opendir-Funktion in C

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);
}
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

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

Verwandter Artikel - C File