Wie scannen Sie ein Verzeichnis für Ordner und Dateien in C? Es muss plattformübergreifend sein.Wie erhalten Sie eine Verzeichnisliste in C?
Antwort
opendir/readdir sind POSIX. Wenn POSIX nicht genug für die Portabilität Sie erreichen wollen, überprüfen Apache Portable Runtime
Im Folgenden werden die Namen der Dateien im aktuellen Verzeichnis drucken:
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main (void)
{
DIR *dp;
struct dirent *ep;
dp = opendir ("./");
if (dp != NULL)
{
while (ep = readdir (dp))
puts (ep->d_name);
(void) closedir (dp);
}
else
perror ("Couldn't open the directory");
return 0;
}
(credit: http://www.gnu.org/software/libtool/manual/libc/Simple-Directory-Lister.html)
Die Die strikte Antwort lautet "Sie können nicht", da das Konzept eines Ordners nicht wirklich plattformübergreifend ist.
Auf MS-Plattformen können Sie _findfirst, _findnext und _findclose für eine 'c' Art von Gefühl und FindFirstFile und FindNextFile für die zugrundeliegenden Win32-Aufrufe verwenden.
Hier ist der C-FAQ Antwort:
Gibt es einen Alias bereits für _findfirst, _findnext und _findclose irgendwo eingerichtet? nicht in windows.h richtig? – BuddyJoe
Es gibt keine Standard-C (oder C++) Methode, um Dateien in einem Verzeichnis aufzulisten.
Unter Windows können Sie die Funktionen FindFirstFile/FindNextFile verwenden, um alle Einträge in einem Verzeichnis aufzulisten. Unter Linux/OSX benutzen Sie die Funktionen opendir/readdir/closedir.
Die Verzeichnisliste variiert stark je nach Betriebssystem/Plattform. Dies liegt daran, dass verschiedene Betriebssysteme ihre eigenen internen Systemaufrufe verwenden, um dies zu erreichen.
Eine Lösung für dieses Problem wäre, nach einer Bibliothek zu suchen, die dieses Problem maskiert und portierbar ist. Leider gibt es keine Lösung, die auf allen Plattformen einwandfrei funktioniert.
Auf POSIX-kompatiblen Systemen könnten Sie die Bibliothek verwenden, um dies mithilfe des von Clayton (der ursprünglich von der Advanced Programming unter UNIX-Buch von W. Richard Stevens stammt) veröffentlichten Codes zu erreichen. Diese Lösung funktioniert unter * NIX-Systemen und würde auch unter Windows funktionieren, wenn Sie Cygwin installiert haben.
Alternativ könnten Sie einen Code schreiben, um das zugrunde liegende Betriebssystem zu erkennen und dann die entsprechende Verzeichnisauflistungsfunktion aufrufen, die die "richtige" Möglichkeit zum Auflisten der Verzeichnisstruktur unter diesem Betriebssystem enthält.
GLib ist eine Portabilität/Utility-Bibliothek für C, die die Grundlage des GTK + grafischen Toolkits bildet. Es kann als eigenständige Bibliothek verwendet werden.
Es enthält portable Wrapper zum Verwalten von Verzeichnissen. Einzelheiten finden Sie in der Dokumentation Glib File Utilities.
Persönlich würde ich nicht einmal in Erwägung ziehen, große Mengen an C-Code ohne etwas wie GLib hinter mir zu schreiben. Portabilität ist eine Sache, aber es ist auch nett, Datenstrukturen, Threadhelfer, Ereignisse, Hauptschleifen etc. für freies zu erhalten
Jikes, ich fange fast an, wie ein Verkaufstyp zu klingen :) (mach dir keine Sorgen, glib ist Open Source (LGPL) und ich bin nicht mit ihm in irgendeiner Weise)
+1; Die relevante Funktion ist 'g_dir_read_name()' – weiqure
die ähnliche Methode readdir
wird wahrscheinlich mit dem wenig bekannten _find
family of functions dem Unternehmen assoziiert.
Ich habe eine Open Source (BSD) C-Header erstellt, die dieses Problem behandelt. Es unterstützt derzeit POSIX und Windows. Bitte überprüfen Sie es heraus:
https://github.com/cxong/tinydir
tinydir_dir dir;
tinydir_open(&dir, "/path/to/dir");
while (dir.has_next)
{
tinydir_file file;
tinydir_readfile(&dir, &file);
printf("%s", file.name);
if (file.is_dir)
{
printf("/");
}
printf("\n");
tinydir_next(&dir);
}
tinydir_close(&dir);
Wie hilft das mehr als die ursprünglichen systemabhängigen Implementierungen? Oder ist es so, dass Sie nur eine benannte Bibliothek für Windows und POSIX benötigen? – kevr
'Abstimmung' für tinydir.h, Gut gemacht. –
Sie können den Beispielcode auf dem wikibooks link finden
/**************************************************************
* A simpler and shorter implementation of ls(1)
* ls(1) is very similar to the DIR command on DOS and Windows.
**************************************************************/
#include <stdio.h>
#include <dirent.h>
int listdir(const char *path)
{
struct dirent *entry;
DIR *dp;
dp = opendir(path);
if (dp == NULL)
{
perror("opendir");
return -1;
}
while((entry = readdir(dp)))
puts(entry->d_name);
closedir(dp);
return 0;
}
int main(int argc, char **argv) {
int counter = 1;
if (argc == 1)
listdir(".");
while (++counter <= argc) {
printf("\nListing %s...\n", argv[counter-1]);
listdir(argv[counter-1]);
}
return 0;
}
Dies sollte auch, zumindest mit MinGW unter Windows arbeiten. –
@Clayton aber ich habe gelernt, dass nie puts() verwenden, da es nicht wissen, wie viele Zeichen zu drucken? – YakRangi
Was ist das: 'Fehler: unbekannter Typ Name 'off64_t'' –