Usa la funzione opendir in C

Jinku Hu 12 ottobre 2023
  1. Utilizzare la funzione opendir per aprire un flusso di directory
  2. Utilizzare la funzione readdir per ripetere le voci di directory
Usa la funzione opendir in C

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);
}
Autore: 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

Articolo correlato - C File