GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie verwendet man scandir() in c richtig?

Dies ist eine alte Frage, aber da ich darauf gestoßen bin und sie meine Frage nicht so effektiv gelöst hat wie die Manpage, kopiere ich ein Code-Snippet von der Manpage als neue Antwort für die Zukunft.

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

Die Funktion scandir() weist den Speicher für Sie zu.

Sie müssen KEINEN Speicher zuweisen. Sie TUN müssen den von scandir() zurückgegebenen Speicher freigeben .

Ihr Code ruft auf:*noOfFiles = scandir(path, &fileListTemp, NULL, alphasort);

Bei Rückgabe noOfFiles enthält die Anzahl der Telefonbucheinträge im path Verzeichnis und fileListTemp zeigt auf ein zugewiesenes Array von Zeigern auf ein zugewiesenes struct dirent Blobs, von denen jeder einen d_name hat Mitglied, das auf den nullterminierten Namen einer Datei/eines Verzeichnisses zeigt.

Wenn Ihr Verzeichnis beispielsweise die Dateien "ErsteDatei.txt", "AnotherFile.txt", "ThirdFile.txt" enthält, bei Ihrem Aufruf, bei Rückkehr von scandir() , noOfFiles wird auf 5 gesetzt für die drei Dateien plus zwei weitere für das "." und ".." Verzeichniseinträge. DIE EINTRAGE WERDEN IN KEINER BESTIMMTEN REIHENFOLGE ERFOLGEN, WENN SIE 'alphasort' NICHT BESTEHEN. (Eigentlich ist das ein wenig falsch. Sie werden in der Reihenfolge der Dateinameneinträge im Verzeichnis stehen, was von der Reihenfolge abhängt, in der die Dateien ursprünglich erstellt wurden.)

Da Sie 'alphasort' übergeben haben, sollten Sie die Einträge in der folgenden Reihenfolge sehen (ich zeige explizit das 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 zeigt also auf einen Block mit zugewiesenem Speicher, der fünf struct dirent enthält Zeiger. Jeder der fünf struct dirent Zeiger zeigen auf ein struct dirent Block des zugewiesenen Speichers, der einen nullterminierten Verzeichniseintragsnamen in d_name enthält Mitglied. (Auch dies ist eine Vereinfachung, da der Eintrag d_name ebenfalls ein Zeiger ist, aber er zeigt auf zusätzlich zugewiesenen Platz am hinteren Ende des zugewiesenen Blocks, und der Eintragsname wird dort gespeichert.)

Das ist SECHS Blöcke des zugewiesenen Speichers.

Sie können diesen zugewiesenen Speicher verwenden, bis Sie damit fertig sind, und dann rufen Sie free() für JEDEN Eintrag im Array auf, gefolgt von free() des Arrays selbst.

Sie MÜSSEN jeden Eintrag sowie das Array selbst freigeben. Sie sind alle unabhängig zugewiesene Speicherblöcke.

Wenn Sie mit der Liste fertig sind, sollten Sie:

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

free(fileListTemp);

Linux
  1. So verwenden Sie BusyBox unter Linux

  2. So verwenden Sie Bash-Verlaufsbefehle

  3. Wie ich Cron unter Linux verwende

  4. So verwenden Sie Nginx zum Umleiten

  5. wie man $1 richtig in einem Alias ​​mit zwei Argumenten verwendet

So verwenden Sie den Linux-SS-Befehl

So verwenden Sie den Linux-nohup-Befehl

So verwenden Sie Instagram im Terminal

So verwenden Sie den PS-Befehl

So verwenden Sie den TOP-Befehl

So verwenden Sie FTP