GNU/Linux >> Znalost Linux >  >> Linux

Jak správně používat scandir() v c?

Toto je stará otázka, ale protože jsem na ni narazil a nevyřešila mou otázku tak efektivně jako manuálová stránka, zkopíruji úryvek kódu z manuálové stránky jako novou odpověď pro budoucnost.

  #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);
       }
   }

Funkce scandir() přiděluje paměť za vás.

Nemusíte přidělovat ŽÁDNOU paměť. Vy DĚLÁTE potřebujete uvolnit paměť vrácenou do scandir() .

Váš kód volá:*noOfFiles = scandir(path, &fileListTemp, NULL, alphasort);

Při návratu noOfFiles bude obsahovat počet položek adresáře v path adresář a fileListTemp bude ukazovat na přidělené pole ukazatelů na přidělené struct dirent bloby, z nichž každý má d_name člen, který ukazuje na název souboru/adresáře zakončený nulou.

Pokud váš adresář obsahuje soubory "FirstFile.txt", "AnotherFile.txt", "ThirdFile.txt", například s vaším voláním, po návratu z scandir() , noOfFiles bude nastaveno na 5 pro tři soubory plus dva další pro "." a ".." položky adresáře. POKUD NEPRODEJTE 'alphasort', NEBUDOU V ŽÁDNÉM KONKRÉTNÍM POŘADÍ. (Ve skutečnosti je to trochu nesprávné. Budou v pořadí položek názvu souboru adresáře, které závisí na pořadí, ve kterém byly soubory původně vytvořeny.)

Protože jste předali 'alphasort', měli byste vidět položky v následujícím pořadí (výslovně ukazuji 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"

FileListTemp tedy ukazuje na blok alokované paměti obsahující pět struct dirent ukazatele. Každý z pěti struct dirent ukazatele ukazují na struct dirent blok alokované paměti obsahující název položky adresáře ukončený nulou v d_name člen. (I to je zjednodušení, protože položka d_name je také ukazatel, ale ukazuje na další přidělený prostor na konci přiděleného bloku a tam je uložen název položky.)

To je SIX bloky přidělené paměti.

Tuto přidělenou paměť můžete používat, dokud s ní neskončíte, a pak zavoláte free() na KAŽDOU položku v poli a následně free() samotného pole.

MUSÍTE uvolnit každý záznam i pole samotné. Všechny jsou nezávisle přidělené bloby paměti.

Až budete se seznamem hotovi, měli byste:

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

free(fileListTemp);

Linux
  1. Jak používat BusyBox na Linuxu

  2. Jak používat příkazy historie Bash

  3. Jak používám cron v Linuxu

  1. Jak používat FIND v Linuxu

  2. Jak používat Nginx k přesměrování

  3. Jak používat Su Command v Linuxu

  1. jak používat pylint ve vim

  2. Jak používat dos2unix?

  3. jak správně použít $1 v aliasu se dvěma argumenty