2008-08-15 7 views

Antwort

5

opendir/readdir sind POSIX. Wenn POSIX nicht genug für die Portabilität Sie erreichen wollen, überprüfen Apache Portable Runtime

68

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)

+1

Dies sollte auch, zumindest mit MinGW unter Windows arbeiten. –

+1

@Clayton aber ich habe gelernt, dass nie puts() verwenden, da es nicht wissen, wie viele Zeichen zu drucken? – YakRangi

+0

Was ist das: 'Fehler: unbekannter Typ Name 'off64_t'' –

18

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:

http://c-faq.com/osdep/readdir.html

+0

Gibt es einen Alias ​​bereits für _findfirst, _findnext und _findclose irgendwo eingerichtet? nicht in windows.h richtig? – BuddyJoe

9

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.

+0

Boost :: Dateisystem? – paxos1977

+1

@ceretullis: Beachten Sie das Wort "Standard" .. Boost ist noch nicht Standard .. – krebstar

+23

Boost ist auch nicht C. –

2

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.

7

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)

+2

+1; Die relevante Funktion ist 'g_dir_read_name()' – weiqure

13

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); 
+0

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

+0

'Abstimmung' für tinydir.h, Gut gemacht. –

-1

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