GNU/Linux >> Linux Esercitazione >  >> Linux

Come usare correttamente scandir() in c?

Questa è una vecchia domanda, ma dal momento che l'ho trovata e non ha risolto la mia domanda in modo efficace come ha fatto la pagina man, sto copiando un frammento di codice dalla pagina man come nuova risposta per il futuro.

  #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 funzione scandir() alloca la memoria per te.

Non è necessario allocare NESSUNA memoria. Tu FAI devi liberare la memoria che ti è stata restituita da scandir() .

Il tuo codice chiama:*noOfFiles = scandir(path, &fileListTemp, NULL, alphasort);

Al ritorno, noOfFiles conterrà il numero di voci di directory nel path directory e fileListTemp punterà a un array allocato di puntatori a struct dirent allocato blob ognuno dei quali ha un d_name membro che punta al nome con terminazione nulla di un file/directory.

Se la tua directory contiene i file "FirstFile.txt", "AnotherFile.txt", "ThirdFile.txt", ad esempio, con la tua chiamata, al ritorno da scandir() , noOfFiles sarà impostato su 5 per i tre file più altri due per il "." e voci di directory ".." LE ISCRIZIONI SARANNO IN NESSUN ORDINE PARTICOLARE SE NON PASSI 'alphasort'. (In realtà è un po' errato. Saranno nell'ordine delle voci del nome file della directory che dipende dall'ordine in cui i file sono stati originariamente creati.)

Poiché hai passato 'alphasort' dovresti vedere le voci nel seguente ordine (sto mostrando esplicitamente il terminatore di stringhe di byte nullo:

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"

Quindi fileListTemp punta a un blocco di memoria allocata contenente cinque struct dirent puntatori. Ognuna delle cinque struct dirent i puntatori puntano a una struct dirent blocco di memoria allocata contenente un nome di voce di directory con terminazione null in d_name membro. (Anche questa è una semplificazione, perché anche la voce d_name è un puntatore, ma punta a uno spazio extra allocato alla fine del blocco allocato, e il nome della voce è memorizzato lì.)

Questo è SEI blocchi di memoria allocata.

Puoi utilizzare questa memoria allocata fino a quando non hai finito, quindi chiami free() su OGNI voce nell'array seguita da free() dell'array stesso.

DEVI liberare ogni voce così come l'array stesso. Sono tutti blob di memoria allocati in modo indipendente.

Quando hai finito con l'elenco dovresti:

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

free(fileListTemp);

Linux
  1. Come usare BusyBox su Linux

  2. Come usare i comandi della cronologia di Bash

  3. Come uso cron in Linux

  4. Come usare TROVA in Linux

  5. Come utilizzare Nginx per reindirizzare

Come utilizzare il comando SS di Linux

Come usare il comando nohup di Linux

Come utilizzare Instagram nel terminale

Come usare il comando PS

Come usare il comando TOP

Come utilizzare FTP