it-swarm.com.de

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

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

Ich darf den Befehl ls nicht ausführen und die Ergebnisse aus meinem Programm heraus analysieren.

489
samoz

Bei kleinen und einfachen Aufgaben verwende ich keinen Boost, ich verwende dirent.h, das auch für Windows verfügbar ist:

DIR *dir;
struct dirent *ent;
if ((dir = opendir ("c:\\src\\")) != NULL) {
  /* print all the files and directories within directory */
  while ((ent = readdir (dir)) != NULL) {
    printf ("%s\n", ent->d_name);
  }
  closedir (dir);
} else {
  /* could not open directory */
  perror ("");
  return EXIT_FAILURE;
}

Es ist nur eine kleine Header-Datei und erledigt die meisten einfachen Dinge, die Sie benötigen, ohne einen großen vorlagenbasierten Ansatz wie Boost zu verwenden (kein Angriff, ich mag Boost!).

Der Autor der Windows-Kompatibilitätsebene ist Toni Ronkko. Bei Unix handelt es sich um einen Standardheader.

UPDATE 2017:

In C++ 17 gibt es jetzt eine offizielle Möglichkeit, Dateien Ihres Dateisystems aufzulisten: std::filesystem. Es gibt eine ausgezeichnete Antwort aus Shreevardhan unten mit diesem Quellcode:

#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;
}
686
Peter Parker

C++ 17 hat jetzt einen std::filesystem::directory_iterator , der als verwendet werden kann

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

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

236
Shreevardhan

Leider definiert der C++ - Standard keine Standardmethode für das Arbeiten mit Dateien und Ordnern auf diese Weise. 

Da es keine plattformübergreifende Methode gibt, ist die beste plattformübergreifende Methode die Verwendung einer Bibliothek wie boost filesystem module .

Plattformübergreifende Boost-Methode:

Wenn die folgende Funktion einen Verzeichnispfad und einen Dateinamen enthält, durchsucht das Verzeichnis und seine Unterverzeichnisse rekursiv nach dem Dateinamen. Dabei wird ein Bool und bei Erfolg der Pfad der gefundenen Datei zurückgegeben. 

bool find_file(const path & dir_path,         // in this directory,
               const std::string & file_name, // search for this name,
               path & path_found)             // placing path here if found
{
    if (!exists(dir_path)) 
        return false;

    directory_iterator end_itr; // default construction yields past-the-end

    for (directory_iterator itr(dir_path); itr != end_itr; ++itr)
    {
        if (is_directory(itr->status()))
        {
            if (find_file(itr->path(), file_name, path_found)) 
                return true;
        }
        else if (itr->leaf() == file_name) // see below
        {
            path_found = itr->path();
            return true;
        }
    }
    return false;
}

Quelle von der oben genannten Boost-Seite.


Für Unix/Linux-basierte Systeme: 

Sie können opendirreaddir / closedir verwenden. 

Ein Beispielcode, der ein Verzeichnis nach dem Eintrag "name" durchsucht, lautet:

   len = strlen(name);
   dirp = opendir(".");
   while ((dp = readdir(dirp)) != NULL)
           if (dp->d_namlen == len && !strcmp(dp->d_name, name)) {
                   (void)closedir(dirp);
                   return FOUND;
           }
   (void)closedir(dirp);
   return NOT_FOUND;

Quellcode von den obigen Manpages.


_/Für Windows-basierte Systeme: 

sie können die Win32-API-Funktionen FindFirstFile / FindNextFile / FindClose verwenden.

Das folgende C++ - Beispiel zeigt eine minimale Verwendung von FindFirstFile.

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

void _tmain(int argc, TCHAR *argv[])
{
   WIN32_FIND_DATA FindFileData;
   HANDLE hFind;

   if( argc != 2 )
   {
      _tprintf(TEXT("Usage: %s [target_file]\n"), argv[0]);
      return;
   }

   _tprintf (TEXT("Target file is %s\n"), argv[1]);
   hFind = FindFirstFile(argv[1], &FindFileData);
   if (hFind == INVALID_HANDLE_VALUE) 
   {
      printf ("FindFirstFile failed (%d)\n", GetLastError());
      return;
   } 
   else 
   {
      _tprintf (TEXT("The first file found is %s\n"), 
                FindFileData.cFileName);
      FindClose(hFind);
   }
}

Quellcode von den obigen Msdn-Seiten.

219
Brian R. Bondy

Eine Funktion genügt, Sie müssen keine Drittanbieter-Bibliothek (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önnen Sie *.* in *.ext ändern, um nur die EXT-Dateien (d. H. Eines bestimmten Typs) in diesem Verzeichnis zu erhalten.

75
herohuyongtao

Für eine reine C-Lösung überprüfen Sie dies bitte. Es ist nur ein zusätzlicher Header erforderlich:

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

Einige Vorteile gegenüber anderen Optionen:

  • Es ist portabel - umschließt POSIX Dirent und Windows FindFirstFile
  • Es verwendet, soweit verfügbar, readdir_r, was bedeutet, dass es normalerweise threadsicher ist
  • Unterstützt Windows UTF-16 über dieselben UNICODE-Makros
  • Es ist C90, also können auch sehr alte Compiler damit arbeiten
46
congusbongus

Ich empfehle die Verwendung von glob mit diesem wiederverwendbaren Wrapper. Es generiert einen vector<string>, der den Dateipfaden entspricht, die in das Glob-Muster passen:

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

Das kann dann mit einem normalen System-Platzhaltermuster aufgerufen werden, z.

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

Hier ist ein sehr einfacher Code in C++11, der boost::filesystem-Bibliothek verwendet, um Dateinamen in einem Verzeichnis (mit Ausnahme von Ordnernamen) abzurufen:

#include <string>
#include <iostream>
#include <boost/filesystem.hpp>
using namespace std;
using namespace boost::filesystem;

int main()
{
    path p("D:/AnyFolder");
    for (auto i = directory_iterator(p); i != directory_iterator(); i++)
    {
        if (!is_directory(i->path())) //we eliminate directories
        {
            cout << i->path().filename().string() << endl;
        }
        else
            continue;
    }
}

Ausgabe ist wie:

file1.txt
file2.dat
21
Bad

Warum nicht glob() verwenden?

#include <glob.h>

glob_t glob_result;
glob("/your_directory/*",GLOB_TILDE,NULL,&glob_result);
for(unsigned int i=0; i<glob_result.gl_pathc; ++i){
  cout << glob_result.gl_pathv[i] << endl;
}
17
Meekohi

Ich denke, der folgende Ausschnitt kann verwendet werden, um alle Dateien aufzulisten.

#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>

static void list_dir(const char *path)
{
    struct dirent *entry;
    DIR *dir = opendir(path);
    if (dir == NULL) {
        return;
    }

    while ((entry = readdir(dir)) != NULL) {
        printf("%s\n",entry->d_name);
    }

    closedir(dir);
}

Nachfolgend ist die Struktur des struct dirent dargestellt

struct dirent {
    ino_t d_ino; /* inode number */
    off_t d_off; /* offset to the next dirent */
    unsigned short d_reclen; /* length of this record */
    unsigned char d_type; /* type of file */
    char d_name[256]; /* filename */
};
16
Shrikant

Testen Sie die x-Plattform-Methode

http://www.boost.org/doc/libs/1_38_0/libs/filesystem/doc/index.htm

oder verwenden Sie einfach Ihre betriebssystemspezifischen Dateien.

10
Tim

Schauen Sie sich diese Klasse an, die die Win32-API verwendet. Erstellen Sie einfach eine Instanz, indem Sie die Variable foldername bereitstellen, aus der Sie die Auflistung erstellen möchten. Rufen Sie dann die Methode getNextFile auf, um die nächste Variable filename aus dem Verzeichnis abzurufen. Ich denke es braucht windows.h und stdio.h.

class FileGetter{
    WIN32_FIND_DATAA found; 
    HANDLE hfind;
    char folderstar[255];       
    int chk;

public:
    FileGetter(char* folder){       
        sprintf(folderstar,"%s\\*.*",folder);
        hfind = FindFirstFileA(folderstar,&found);
        //skip .
        FindNextFileA(hfind,&found);        
    }

    int getNextFile(char* fname){
        //skips .. when called for the first time
        chk=FindNextFileA(hfind,&found);
        if (chk)
            strcpy(fname, found.cFileName);     
        return chk;
    }

};
8
robertvarga

GNU-Handbuch FTW

http://www.gnu.org/software/libc/manual/html_node/Simple-Directory-Lister.html#Simple-Directory-Lister

Manchmal ist es auch gut, direkt zur Quelle zu gehen (Wortspiel beabsichtigt). Sie können viel lernen, wenn Sie sich die Innenseiten einiger der häufigsten Befehle in Linux ansehen. Ich habe einen einfachen Spiegel der GNU-Coreutils auf Github (zum Lesen) eingerichtet.

https://github.com/homer6/gnu_coreutils/blob/master/src/ls.c

Vielleicht wird Windows nicht angesprochen, aber es gibt eine Reihe von Fällen, in denen Unix-Varianten verwendet werden.

Hoffentlich hilft das...

6
Homer6
char **getKeys(char *data_dir, char* tablename, int *num_keys)
{
    char** arr = malloc(MAX_RECORDS_PER_TABLE*sizeof(char*));
int i = 0;
for (;i < MAX_RECORDS_PER_TABLE; i++)
    arr[i] = malloc( (MAX_KEY_LEN+1) * sizeof(char) );  


char *buf = (char *)malloc( (MAX_KEY_LEN+1)*sizeof(char) );
snprintf(buf, MAX_KEY_LEN+1, "%s/%s", data_dir, tablename);

DIR* tableDir = opendir(buf);
struct dirent* getInfo;

readdir(tableDir); // ignore '.'
readdir(tableDir); // ignore '..'

i = 0;
while(1)
{


    getInfo = readdir(tableDir);
    if (getInfo == 0)
        break;
    strcpy(arr[i++], getInfo->d_name);
}
*(num_keys) = i;
return arr;
}
4
JasonYen2205

Ich hoffe, dieser Code hilft dir.

#include <windows.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

string wchar_t2string(const wchar_t *wchar)
{
    string str = "";
    int index = 0;
    while(wchar[index] != 0)
    {
        str += (char)wchar[index];
        ++index;
    }
    return str;
}

wchar_t *string2wchar_t(const string &str)
{
    wchar_t wchar[260];
    int index = 0;
    while(index < str.size())
    {
        wchar[index] = (wchar_t)str[index];
        ++index;
    }
    wchar[index] = 0;
    return wchar;
}

vector<string> listFilesInDirectory(string directoryName)
{
    WIN32_FIND_DATA FindFileData;
    wchar_t * FileName = string2wchar_t(directoryName);
    HANDLE hFind = FindFirstFile(FileName, &FindFileData);

    vector<string> listFileNames;
    listFileNames.Push_back(wchar_t2string(FindFileData.cFileName));

    while (FindNextFile(hFind, &FindFileData))
        listFileNames.Push_back(wchar_t2string(FindFileData.cFileName));

    return listFileNames;
}

void main()
{
    vector<string> listFiles;
    listFiles = listFilesInDirectory("C:\\*.txt");
    for each (string str in listFiles)
        cout << str << endl;
}
3
Yas

sie können alle direkten Dateien in Ihrem Stammverzeichnis abrufen, indem Sie std :: experimental :: filesystem :: directory_iterator () verwenden. Lesen Sie dann den Namen dieser Pfaddateien.

#include <iostream>
#include <filesystem>
#include <string>
#include <direct.h>
using namespace std;
namespace fs = std::experimental::filesystem;
void ShowListFile(string path)
{
for(auto &p: fs::directory_iterator(path))  /*get directory */
     cout<<p.path().filename()<<endl;   // get file name
}

int main() {

ShowListFile("C:/Users/Dell/Pictures/Camera Roll/");
getchar();
return 0;
}
2
ducPham

Das funktioniert für mich. Es tut mir leid, wenn ich mich nicht an die Quelle erinnern kann. Es ist wahrscheinlich von einer Manpage.

#include <ftw.h>

int AnalizeDirectoryElement (const char *fpath, 
                            const struct stat *sb,
                            int tflag, 
                            struct FTW *ftwbuf) {

  if (tflag == FTW_F) {
    std::string strFileName(fpath);

    DoSomethingWith(strFileName);
  }
  return 0; 
}

void WalkDirectoryTree (const char * pchFileName) {

  int nFlags = 0;

  if (nftw(pchFileName, AnalizeDirectoryElement, 20, nFlags) == -1) {
    perror("nftw");
  }
}

int main() {
  WalkDirectoryTree("some_dir/");
}
2
ENHering

Die Antwort von Shreevardhan funktioniert großartig. Wenn Sie es in c ++ 14 verwenden möchten, nehmen Sie einfach eine Änderung vor namespace fs = experimental::filesystem;

d.h.

#include <string>
#include <iostream>
#include <filesystem>

using namespace std;
namespace fs = experimental::filesystem;

int main()
{
    string path = "C:\\splits\\";
    for (auto & p : fs::directory_iterator(path))
        cout << p << endl;
    int n;
    cin >> n;
}
2
Venkat Vinay

Diese Implementierung realisiert Ihren Zweck und füllt dynamisch ein Array von Strings mit dem Inhalt des angegebenen Verzeichnisses.

int exploreDirectory(const char *dirpath, char ***list, int *numItems) {
    struct dirent **direntList;
    int i;
    errno = 0;

    if ((*numItems = scandir(dirpath, &direntList, NULL, alphasort)) == -1)
        return errno;

    if (!((*list) = malloc(sizeof(char *) * (*numItems)))) {
        fprintf(stderr, "Error in list allocation for file list: dirpath=%s.\n", dirpath);
        exit(EXIT_FAILURE);
    }

    for (i = 0; i < *numItems; i++) {
        (*list)[i] = stringDuplication(direntList[i]->d_name);
    }

    for (i = 0; i < *numItems; i++) {
        free(direntList[i]);
    }

    free(direntList);

    return 0;
}
2

Diese Antwort sollte für Windows-Benutzer funktionieren, die Probleme damit hatten, mit Visual Studio mit einer der anderen Antworten zusammenzuarbeiten.

  1. Laden Sie die Datei dirent.h von der Github-Seite herunter. Es ist jedoch besser, nur die Datei Raw dirent.h zu verwenden und die folgenden Schritte auszuführen (so habe ich es zum Laufen gebracht).

    Github-Seite für dirent.h für Windows: Github-Seite für dirent.h

    Raw Dirent File: Raw dirent.h File

  2. Gehen Sie zu Ihrem Projekt und fügen Sie ein neues Objekt hinzu (Ctrl+Shift+A). Fügen Sie eine Header-Datei (.h) hinzu und nennen Sie sie dirent.h.

  3. Fügen Sie den Code Raw dirent.h File in Ihre Kopfzeile ein.

  4. Fügen Sie "dirent.h" in Ihren Code ein.

  5. Fügen Sie die folgende Methode void filefinder() in Ihren Code ein und rufen Sie sie von Ihrer Funktion main aus auf, oder bearbeiten Sie die Funktion, wie Sie sie verwenden möchten.

    #include <stdio.h>
    #include <string.h>
    #include "dirent.h"
    
    string path = "C:/folder"; //Put a valid path here for folder
    
    void filefinder()
    {
        DIR *directory = opendir(path.c_str());
        struct dirent *direntStruct;
    
        if (directory != NULL) {
            while (direntStruct = readdir(directory)) {
                printf("File Name: %s\n", direntStruct->d_name); //If you are using <stdio.h>
                //std::cout << direntStruct->d_name << std::endl; //If you are using <iostream>
            }
        }
        closedir(directory);
    }
    
1
ZKR

System nennen es!

system( "dir /b /s /a-d * > file_names.txt" );

Dann lesen Sie einfach die Datei.

BEARBEITEN: Diese Antwort sollte als Hack angesehen werden, funktioniert jedoch (wenn auch plattformspezifisch), wenn Sie nicht auf elegantere Lösungen zugreifen können.

1
Catalyst

Ich habe versucht, dem Beispiel in bothanswers zu folgen, und es lohnt sich zu beachten, dass std::filesystem::directory_entry so geändert wurde, dass der <<-Operator nicht überladen wird. Anstelle von std::cout << p << std::endl; musste ich Folgendes verwenden, um kompilieren und funktionieren zu können:

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

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

der Versuch, p alleine an std::cout << zu übergeben, führte zu einem fehlenden Überlastungsfehler.

0
StarKiller4011

Da Dateien und Unterverzeichnisse eines Verzeichnisses im Allgemeinen in einer Baumstruktur gespeichert werden, ist die Verwendung des DFS-Algorithmus eine intuitive Methode, um jedes Verzeichnis rekursiv zu durchlaufen. Hier ist ein Beispiel für ein Windows-Betriebssystem, in dem grundlegende Dateifunktionen in io.h verwendet werden. Sie können diese Funktionen auf einer anderen Plattform ersetzen. Ich möchte ausdrücken, dass die Grundidee von DFS dieses Problem perfekt erfüllt. 

#include<io.h>
#include<iostream.h>
#include<string>
using namespace std;

void TraverseFilesUsingDFS(const string& folder_path){
   _finddata_t file_info;
   string any_file_pattern = folder_path + "\\*";
   intptr_t handle = _findfirst(any_file_pattern.c_str(),&file_info);
   //If folder_path exsist, using any_file_pattern will find at least two files "." and "..", 
   //of which "." means current dir and ".." means parent dir
   if (handle == -1){
       cerr << "folder path not exist: " << folder_path << endl;
       exit(-1);
   }
   //iteratively check each file or sub_directory in current folder
   do{
       string file_name=file_info.name; //from char array to string
       //check whtether it is a sub direcotry or a file
       if (file_info.attrib & _A_SUBDIR){
            if (file_name != "." && file_name != ".."){
               string sub_folder_path = folder_path + "\\" + file_name;                
               TraverseFilesUsingDFS(sub_folder_path);
               cout << "a sub_folder path: " << sub_folder_path << endl;
            }
       }
       else
            cout << "file name: " << file_name << endl;
    } while (_findnext(handle, &file_info) == 0);
    //
    _findclose(handle);
}
0
tkingcer

Nur etwas, das ich teilen möchte und danke Ihnen für das Lesematerial. Spielen Sie ein wenig mit der Funktion, um sie zu verstehen. Vielleicht gefällt es dir. e stand für die Erweiterung, p steht für Pfad und s steht für Pfadtrennzeichen. 

Wenn der Pfad ohne Trennzeichen abgeschlossen wird, wird ein Trennzeichen an den Pfad angehängt. Wenn für die Erweiterung eine leere Zeichenfolge eingegeben wird, gibt die Funktion eine Datei zurück, die keine Erweiterung im Namen hat. Wenn ein einzelner Stern eingegeben wurde, werden alle Dateien im Verzeichnis zurückgegeben. Wenn die Länge von e größer als 0 ist, aber kein einzelnes * ist, wird ein Punkt vor e gesetzt, wenn e keinen Punkt an der Nullposition enthält.

Für einen wiederkehrenden Wert. Wenn eine Karte mit einer Länge von null zurückgegeben wird, wurde nichts gefunden, aber das Verzeichnis war in Ordnung. Wenn der Rückgabewert Index 999 enthält, die Kartengröße jedoch nur 1 ist, bedeutet dies, dass beim Öffnen des Verzeichnispfads ein Problem aufgetreten ist.

Beachten Sie, dass diese Funktion aus Gründen der Effizienz in 3 kleinere Funktionen unterteilt werden kann. Darüber hinaus können Sie eine Anruferfunktion erstellen, die anhand der Eingabe ermittelt, welche Funktion sie aufrufen wird. Warum ist das effizienter? Wenn Sie also alles, was eine Datei ist, packen wollen, so wird die Unterfunktion, die zum Abrufen aller Dateien erstellt wurde, nur alle Dateien übernehmen und muss nicht jedes Mal, wenn eine Datei gefunden wurde, eine andere unnötige Bedingung auswerten. 

Dies gilt auch für Dateien, die keine Erweiterung haben. Eine speziell für diesen Zweck erstellte Funktion würde nur dann nach Wetterlage suchen, wenn das gefundene Objekt eine Datei ist und dann, ob der Name der Datei einen Punkt enthält.

Das Speichern ist möglicherweise nicht viel, wenn Sie nur Verzeichnisse mit weniger Dateien lesen. Wenn Sie jedoch eine große Anzahl von Verzeichnissen lesen oder wenn das Verzeichnis mehrere hunderttausend Dateien enthält, kann dies eine große Ersparnis bedeuten.

#include <stdio.h>
#include <sys/stat.h>
#include <iostream>
#include <dirent.h>
#include <map>

std::map<int, std::string> getFile(std::string p, std::string e = "", unsigned char s = '/'){
    if ( p.size() > 0 ){
        if (p.back() != s) p += s;
    }
    if ( e.size() > 0 ){
        if ( e.at(0) != '.' && !(e.size() == 1 && e.at(0) == '*') ) e = "." + e;
    }

    DIR *dir;
    struct dirent *ent;
    struct stat sb;
    std::map<int, std::string> r = {{999, "FAILED"}};
    std::string temp;
    int f = 0;
    bool fd;

    if ( (dir = opendir(p.c_str())) != NULL ){
        r.erase (999);
        while ((ent = readdir (dir)) != NULL){
            temp = ent->d_name;
            fd = temp.find(".") != std::string::npos? true : false;
            temp = p + temp;

            if (stat(temp.c_str(), &sb) == 0 && S_ISREG(sb.st_mode)){
                if ( e.size() == 1 && e.at(0) == '*' ){
                    r[f] = temp;
                    f++;
                } else {
                    if (e.size() == 0){
                        if ( fd == false ){
                            r[f] = temp;
                            f++;
                        }
                        continue;
                    }

                    if (e.size() > temp.size()) continue;

                    if ( temp.substr(temp.size() - e.size()) == e ){
                        r[f] = temp;
                        f++;
                    }
                }
            }
        }

        closedir(dir);
        return r;
    } else {
        return r;
    }
}

void printMap(auto &m){
    for (const auto &p : m) {
        std::cout << "m[" << p.first << "] = " << p.second << std::endl;
    }
}

int main(){
    std::map<int, std::string> k = getFile("./", "");
    printMap(k);
    return 0;
}
0
Kevin Ng