GNU/Linux >> Tutoriels Linux >  >> Linux

Comment utiliser correctement scandir() en c ?

C'est une vieille question, mais comme je suis tombé dessus et que cela n'a pas résolu ma question aussi efficacement que la page de manuel, je copie un extrait de code de la page de manuel comme nouvelle réponse pour l'avenir.

  #include <dirent.h>

   int
   main(void)
   {
       struct dirent **namelist;
       int n;

       n = scandir(".", &namelist, NULL, alphasort);
       if (n < 0)
           perror("scandir");
       else {
           while (n--) {
               printf("%s\n", namelist[n]->d_name);
               free(namelist[n]);
           }
           free(namelist);
       }
   }

La fonction scandir() alloue la mémoire pour vous.

Vous n'avez pas besoin d'allouer AUCUNE mémoire. Vous FAIS besoin de libérer la mémoire qui vous est rendue par scandir() .

Votre code appelle :*noOfFiles = scandir(path, &fileListTemp, NULL, alphasort);

Au retour, noOfFiles contiendra le nombre d'entrées du répertoire dans le path répertoire, et fileListTemp pointera vers un tableau alloué de pointeurs vers struct dirent alloué blobs dont chacun a un d_name membre qui pointe vers le nom terminé par un caractère nul d'un fichier/répertoire.

Si votre répertoire contient les fichiers "FirstFile.txt", "AnotherFile.txt", "ThirdFile.txt", par exemple, avec votre appel, au retour du scandir() , noOfFiles sera défini sur 5 pour les trois fichiers plus deux autres pour le "." et les entrées de répertoire "..". LES ENTRÉES NE SERONT PAS DANS UN ORDRE PARTICULIER SI VOUS NE PASSEZ PAS 'alphasort'. (En fait, c'est un peu incorrect. Ils seront dans l'ordre des entrées de noms de fichiers du répertoire qui dépend de l'ordre dans lequel les fichiers ont été créés à l'origine.)

Parce que vous avez passé 'alphasort', vous devriez voir les entrées dans l'ordre suivant (je montre explicitement le null-byte-string-terminator :

fileListTemp[0]->d_name == ".\0"
fileListTemp[1]->d_name == "..\0"
fileListTemp[2]->d_name == "AnotherFile.txt\0"
fileListTemp[3]->d_name == "FirstFile.txt\0"
fileListTemp[4]->d_name == "ThirdFile.txt\0"

Ainsi, fileListTemp pointe vers un bloc de mémoire allouée contenant cinq struct dirent pointeurs. Chacun des cinq struct dirent les pointeurs pointent vers un struct dirent bloc de mémoire allouée contenant un nom d'entrée de répertoire terminé par un caractère nul dans le d_name membre. (Même ceci est une simplification, car l'entrée d_name est également un pointeur, mais il pointe vers un espace alloué supplémentaire à la fin du bloc alloué, et le nom de l'entrée y est stocké.)

C'est SIX blocs de mémoire allouée.

Vous pouvez utiliser cette mémoire allouée jusqu'à ce que vous en ayez fini, puis vous appelez free() sur CHAQUE entrée du tableau suivi de free() du tableau lui-même.

Vous DEVEZ libérer chaque entrée ainsi que le tableau lui-même. Ce sont tous des blobs de mémoire alloués indépendamment.

Lorsque vous avez terminé avec la liste, vous devez :

for (int i = 0; i < noOfFiles; i++)
  {
  free(fileListTemp[i];
  }

free(fileListTemp);

Linux
  1. Comment utiliser BusyBox sous Linux

  2. Comment utiliser les commandes d'historique de Bash

  3. Comment j'utilise cron sous Linux

  4. Comment utiliser FIND sous Linux

  5. Comment utiliser la commande Su sous Linux

Comment utiliser la commande Linux SS

Comment utiliser la commande Linux nohup

Comment utiliser Instagram dans le terminal

Comment utiliser la commande PS

Comment utiliser la commande TOP

Comment utiliser FTP