Wie kann ich die Liste der Dateien in einem Verzeichnis mit C oder C++ abrufen?

Lesezeit: 1 Minute

Wie kann ich die Liste der Dateien in einem Verzeichnis
samoz

Wie kann ich die Liste der Dateien in einem Verzeichnis in meinem C- oder C++-Code ermitteln?

Ich darf die nicht ausführen ls Befehl und analysieren Sie die Ergebnisse in meinem Programm.

  • Dies ist ein Duplikat von 609236

    – chris

    4. März 2009 um 20:35 Uhr


  • Siehe auch stat() Fehler ‘keine solche Datei oder kein solches Verzeichnis’, wenn der Dateiname von zurückgegeben wird readdir().

    – Jonathan Leffler

    25. Dezember 2014 um 1:54 Uhr

  • @chrish – Ja, aber dieser hat den Klassiker “Ich darf das ‘ls’ nicht ausführen”! Es ist exakt wie ich mich im 1. Jahr der Informatik fühlen würde. ;D <3x

    – James Bedford

    22. Oktober 2016 um 11:50 Uhr


  • C und C++ sind nicht dieselbe Sprache. Daher ist das Verfahren zum Ausführen dieser Aufgabe in beiden Sprachen unterschiedlich. Bitte wählen Sie eine aus und markieren Sie sie entsprechend neu.

    – MDXF

    2. März 2017 um 21:58 Uhr

  • Und keine dieser Sprachen (außer C++ seit C++17) hat überhaupt ein Konzept eines Verzeichnisses – daher hängt jede Antwort wahrscheinlich von Ihrem Betriebssystem oder von Abstraktionsbibliotheken ab, die Sie möglicherweise verwenden.

    – Toby Speight

    20. Februar 2018 um 11:38 Uhr


1647257410 310 Wie kann ich die Liste der Dateien in einem Verzeichnis
Shreevardhan

C++17 hat jetzt eine std::filesystem::directory_iteratordie verwendet werden kann als

#include <string>
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;

int main() {
    std::string path = "/path/to/directory";
    for (const auto & entry : fs::directory_iterator(path))
        std::cout << entry.path() << std::endl;
}

Ebenfalls, std::filesystem::recursive_directory_iterator kann auch die Unterverzeichnisse durchlaufen.

  • AFAIK kann auch in C++14 verwendet werden, dort ist es aber noch experimentell: namespace fs = std::experimental::filesystem; . Es scheint aber ok zu funktionieren.

    – Peter K

    11. Juli 2016 um 8:03 Uhr

  • Dies sollte die bevorzugte Antwort für die aktuelle Verwendung sein (beginnend mit C ++ 17).

    – grüne Diode

    3. Januar 2017 um 18:28 Uhr

  • Beim Vorbeifahren beachten std::filesystem::path zu std::cout, die Anführungszeichen sind in der Ausgabe enthalten. Um dies zu vermeiden, hängen Sie an .string() zum Pfad, um eine explizite statt einer impliziten Konvertierung durchzuführen (hier std::cout << p.string() << std::endl;). Beispiel: coliru.stacked-crooked.com/view?id=a55ea60bbd36a8a3

    – Roi Danton

    13. April 2017 um 9:04 Uhr


  • Was ist mit NICHT-ASCII-Zeichen in Dateinamen? Sollte nicht std::wstring verwendet werden oder was ist der Typ vom Iterator?

    – Snacküberlauf

    19. Januar 2018 um 13:46 Uhr


  • Ich bin mir nicht sicher, ob ich damit alleine bin, aber ohne zu verlinken -lstdc++fsich würde ein bekommen SIGSEGV (Address boundary error). Ich konnte nirgendwo in der Dokumentation finden, dass dies erforderlich war, und Linker gab auch keinen Hinweis. Das hat bei beiden funktioniert g++ 8.3.0 und clang 8.0.0-3. Hat jemand einen Einblick, wo solche Dinge in den Dokumenten/Spezifikationen angegeben sind?

    – schlucken

    2. Juli 2019 um 10:16 Uhr

  • Verwendungszweck: FindFirstFile(TEXT("D:\\IMAGE\\MYDIRECTORY\\*"), &findFileData);

    – Константин Ван

    11. August 2016 um 0:47 Uhr

  • Bei C++14 gibt es das std::experimental::filesystemmit C++17 gibt es std::filesystem, die eine ähnliche Funktionalität wie boost haben (die Bibliotheken sind von boost abgeleitet). Siehe Antwort von Shreevardhan unten.

    – Roi Danton

    13. April 2017 um 7:51 Uhr


  • Für Fenster siehe docs.microsoft.com/en-us/windows/desktop/FileIO/… für Details

    – FindOutIslamNow

    12. November 2018 um 13:43 Uhr

Wie kann ich die Liste der Dateien in einem Verzeichnis
herohuyongtao

Eine Funktion reicht aus, Sie müssen keine Bibliothek von Drittanbietern (für Windows) verwenden.

#include <Windows.h>

vector<string> get_all_files_names_within_folder(string folder)
{
    vector<string> names;
    string search_path = folder + "/*.*";
    WIN32_FIND_DATA fd; 
    HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd); 
    if(hFind != INVALID_HANDLE_VALUE) { 
        do { 
            // read all (real) files in current folder
            // , delete '!' read other 2 default folder . and ..
            if(! (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
                names.push_back(fd.cFileName);
            }
        }while(::FindNextFile(hFind, &fd)); 
        ::FindClose(hFind); 
    } 
    return names;
}

PS: wie von @Sebastian erwähnt, könntest du ändern *.* zu *.ext um nur die EXT-Dateien (dh eines bestimmten Typs) in diesem Verzeichnis zu erhalten.

  • Diese Lösung ist plattformspezifisch. Aus diesem Grund benötigen Sie Bibliotheken von Drittanbietern.

    – kraxor

    29. Mai 2014 um 13:14 Uhr

  • @kraxor Ja, es funktioniert nur unter Windows, aber OP fragt nie nach einer plattformübergreifenden Lösung. Übrigens ziehe ich es immer vor, etwas auszuwählen, ohne 3rd-Libraries zu verwenden (wenn möglich).

    – herohuyongtao

    29. Mai 2014 um 14:13 Uhr


  • @herohuyongtao OP hat nie eine Plattform angegeben, und eine stark plattformabhängige Lösung für eine allgemeine Frage zu geben, kann irreführend sein. (Was ist, wenn es eine einzeilige Lösung gibt, die nur auf PlayStation 3 funktioniert? Ist das hier eine gute Antwort?) Wie ich sehe, haben Sie Ihre Antwort so bearbeitet, dass sie nur unter Windows funktioniert. Ich denke, so ist es in Ordnung.

    – kraxor

    29. Mai 2014 um 17:20 Uhr

  • @herohuyongtao OP erwähnte, dass er ls nicht analysieren kann, was bedeutet, dass er wahrscheinlich auf Unix ist. Trotzdem eine gute Antwort für Windows.

    – Thomas

    18. September 2014 um 21:20 Uhr

  • Am Ende benutzte ich a std::vector<std::wstring> und dann fileName.c_str() anstelle eines Vektors von Zeichenfolgen, die nicht kompilieren würden.

    – PerryC

    12. Juli 2016 um 15:38 Uhr

Für eine reine C-Lösung sehen Sie sich dies bitte an. Es erfordert nur einen zusätzlichen Header:

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("https://stackoverflow.com/");
    }
    printf("\n");

    tinydir_next(&dir);
}

tinydir_close(&dir);

Einige Vorteile gegenüber anderen Optionen:

  • Es ist portabel – umschließt POSIX dirent und Windows FindFirstFile
  • Es benutzt readdir_r wo verfügbar, was bedeutet, dass es (normalerweise) threadsicher ist
  • Unterstützt Windows UTF-16 über dasselbe UNICODE Makros
  • Es ist C90, also können sogar sehr alte Compiler es verwenden

  • Diese Lösung ist plattformspezifisch. Aus diesem Grund benötigen Sie Bibliotheken von Drittanbietern.

    – kraxor

    29. Mai 2014 um 13:14 Uhr

  • @kraxor Ja, es funktioniert nur unter Windows, aber OP fragt nie nach einer plattformübergreifenden Lösung. Übrigens ziehe ich es immer vor, etwas auszuwählen, ohne 3rd-Libraries zu verwenden (wenn möglich).

    – herohuyongtao

    29. Mai 2014 um 14:13 Uhr


  • @herohuyongtao OP hat nie eine Plattform angegeben, und eine stark plattformabhängige Lösung für eine allgemeine Frage zu geben, kann irreführend sein. (Was ist, wenn es eine einzeilige Lösung gibt, die nur auf PlayStation 3 funktioniert? Ist das hier eine gute Antwort?) Wie ich sehe, haben Sie Ihre Antwort so bearbeitet, dass sie nur unter Windows funktioniert. Ich denke, so ist es in Ordnung.

    – kraxor

    29. Mai 2014 um 17:20 Uhr

  • @herohuyongtao OP erwähnte, dass er ls nicht analysieren kann, was bedeutet, dass er wahrscheinlich auf Unix ist. Trotzdem eine gute Antwort für Windows.

    – Thomas

    18. September 2014 um 21:20 Uhr

  • Am Ende benutzte ich a std::vector<std::wstring> und dann fileName.c_str() anstelle eines Vektors von Zeichenfolgen, die nicht kompilieren würden.

    – PerryC

    12. Juli 2016 um 15:38 Uhr

Ich empfehle die Verwendung glob mit dieser wiederverwendbaren Verpackung. Es erzeugt a vector<string> entsprechend Dateipfaden, die dem Glob-Muster entsprechen:

#include <glob.h>
#include <vector>
using std::vector;

vector<string> globVector(const string& pattern){
    glob_t glob_result;
    glob(pattern.c_str(),GLOB_TILDE,NULL,&glob_result);
    vector<string> files;
    for(unsigned int i=0;i<glob_result.gl_pathc;++i){
        files.push_back(string(glob_result.gl_pathv[i]));
    }
    globfree(&glob_result);
    return files;
}

Welches dann mit einem normalen Systemplatzhaltermuster aufgerufen werden kann, wie zum Beispiel:

vector<string> files = globVector("./*");

  • Testen Sie, ob glob() Null zurückgibt.

    – Camille Goudeseune

    21. Mai 2015 um 16:51 Uhr

  • Ich möchte glob.h verwenden, wie Sie es empfohlen haben. Aber trotzdem kann ich die .h-Datei nicht einschließen: Es heißt No such file or directory. Können Sie mir bitte sagen, wie ich dieses Problem lösen kann?

    – Tofu

    23. Februar 2016 um 10:36 Uhr


  • Beachten Sie, dass diese Routine nur eine Ebene tief geht (keine Rekursion). Es führt auch keine schnelle Überprüfung durch, um festzustellen, ob es sich um eine Datei oder ein Verzeichnis handelt, was Sie einfach durch Wechseln tun können GLOB_TILDE mit GLOB_TILDE | GLOB_MARK und dann nach Pfaden suchen, die mit einem Schrägstrich enden. Sie müssen beide Änderungen daran vornehmen, wenn Sie dies benötigen.

    – Wolomike

    15. Mai 2016 um 17:16 Uhr

  • Ist das plattformübergreifend kompatibel?

    – Nikhil Augustinus

    1. Juli 2018 um 7:11 Uhr


  • Leider können Sie über nicht einheitlich versteckte Dateien finden glob.

    – LmTinyToon

    5. Oktober 2018 um 11:30 Uhr

1001320cookie-checkWie kann ich die Liste der Dateien in einem Verzeichnis mit C oder C++ abrufen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy