Hoe kan ik de lijst met bestanden in een map krijgen met C of C++?

Hoe kan ik de lijst met bestanden in een map bepalen vanuit mijn C- of C++-code?

Ik mag de opdracht lsniet uitvoeren en de resultaten ontleden vanuit mijn programma.


Antwoord 1, autoriteit 100%

UPDATE 2017:

In C++17 is er nu een officiële manier om bestanden van je bestandssysteem weer te geven: std::filesystem. Er is een uitstekend antwoord van Shreevardhanhieronder met deze broncode (deze code kan gooien):

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

Oud antwoord:

Bij kleine en eenvoudige taken gebruik ik geen boost, ik gebruik dirent.h. Het is beschikbaar als een standaard header in UNIX, en ook beschikbaar voor Windows via een compatibiliteitslaag gemaakt door Toni Ronkko.

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

Het is slechts een klein kopbalbestand en doet het grootste deel van de eenvoudige dingen die u nodig hebt zonder een grote sjabloongebaseerde aanpak als boost (geen overtreding, ik hou van boost!).


Antwoord 2, Autoriteit 46%

C++ 17 Nu heeft een std::filesystem::directory_iterator, die kan worden gebruikt 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;
}

Ook, std::filesystem::recursive_directory_iteratorkan ook de subdirectories herhalen.


Antwoord 3, Autoriteit 26%

Helaas definieert de C++ -standaard geen standaardmanier om op deze manier met bestanden en mappen te werken.

Aangezien er geen cross-platform-manier is, is de beste cross-platform manier om een ​​bibliotheek te gebruiken, zoals de Boost filesystem module .

Cross Platform Boost-methode:

De volgende functie, gezien een directorypad en een bestandsnaam, zoekt recursief door de map en de submappen voor de bestandsnaam, die een bool retourneren, en indien succesvol, het pad naar het gevonden bestand.

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

Bron van de hierboven genoemde boost-pagina.

Voor op Unix/Linux gebaseerde systemen:

Je kunt opendir/ readdir/ closedir.

Voorbeeldcode die een directory zoekt voor invoer “naam” is:

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;

Broncode van de bovenstaande man-pagina’s.

Voor op Windows gebaseerde systemen:

U kunt de Win32 API gebruiken FindFirstFile/ FindNextFile/ FindClose-functies.

Het volgende C++-voorbeeld toont u een minimaal gebruik van 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);
   }
}

Broncode van de bovenstaande msdn-pagina’s.


Antwoord 4, autoriteit 11%

Eén functie is voldoende, u hoeft geen bibliotheek van derden (voor Windows) te gebruiken.

#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: zoals vermeld door @Sebastian, zou je *.*kunnen veranderen in *.extom alleen de EXT-bestanden te krijgen (dwz van een specifiek type ) in die map.


Antwoord 5, autoriteit 6%

Voor een oplossing met alleen C, bekijk dit alstublieft. Het vereist alleen een extra 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("/");
    }
    printf("\n");
    tinydir_next(&dir);
}
tinydir_close(&dir);

Enkele voordelen ten opzichte van andere opties:

  • Het is draagbaar – omhult POSIX dirent en Windows FindFirstFile
  • Het gebruikt readdir_rwaar beschikbaar, wat betekent dat het (meestal) threadsafe is
  • Ondersteunt Windows UTF-16 via dezelfde UNICODE-macro’s
  • Het is C90, dus zelfs zeer oude compilers kunnen het gebruiken

Antwoord 6, autoriteit 4%

Ik raad aan om globte gebruiken met deze herbruikbare verpakking. Het genereert een vector<string>die overeenkomt met bestandspaden die passen in het glob-patroon:

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

die dan kan worden gebeld met een normaal systeem jokertekenpatroon, zoals:

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

Antwoord 7, Autoriteit 3%

Ik denk dat onder fragment kan worden gebruikt om alle bestanden te vermelden.

#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
int main(int argc, char** argv) { 
    list_dir("myFolderName");
    return EXIT_SUCCESS;
}  
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);
}

Dit is de gebruikte structuur (aanwezig in dirent.h):

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

Antwoord 8, Autoriteit 3%

Hier is een zeer eenvoudige code in C++11met boost::filesystemLibrary om bestandsnamen te krijgen in een map (exclusief mapnamen):

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

Uitgang is als:

file1.txt
file2.dat

Antwoord 9, Autoriteit 3%

Waarom niet gebruiken glob()?

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

Antwoord 10

Probeer Boost voor X-platformmethode

http://www.boost.org/ DOC / LIBS / 1_38_0 / LIBS / FISTONSYSTEM / DOC / INDEX.HTM

of gebruik gewoon uw OS-specifieke bestandsspullen.


Antwoord 11

Bekijk deze klasse die de Win32 API gebruikt. Construeer gewoon een instantie door de foldernamete verstrekken van waaruit u de vermelding wilt, bel dan de getNextFileMethod om de volgende filenameuit de map te krijgen. Ik denk dat het windows.hen stdio.hnodig heeft.

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

Antwoord 12

GNU-handleiding ftw

http://www.gnu.org /Software/libc/manual/html_node/simple-directory-lister.html#simple-directory-lister

Ook is het soms goed om naar rechts te gaan naar de bron (bestemd woordspeling). Je kunt veel leren door te kijken naar de ingewanden van enkele van de meest voorkomende opdrachten in Linux. Ik heb een eenvoudige spiegel opgezet van GNU’s Coreutils op Github (voor het lezen).

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

Misschien kan dit geen vensters aanpakken, maar een aantal gevallen van het gebruik van UNIX-varianten kan worden gehad door deze methoden te gebruiken.

Ik hoop dat dat helpt …


Antwoord 13

Shreeevardhan antwoord werkt geweldig. Maar als u het in C++ 14 wilt gebruiken, maakt u gewoon een wijziging namespace fs = experimental::filesystem;

d.w.z.,

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

Antwoord 14

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

Antwoord 15

Ik hoop dat deze code u helpt.

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

Antwoord 16

Deze implementatie realiseert uw doel, dynamisch een reeks snaren vullen met de inhoud van de opgegeven map.

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

Antwoord 17

Systeem noem het!

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

Lees vervolgens het bestand.

EDIT: Dit antwoord moet worden beschouwd als een hack, maar het werkt echt (zij het op een platform-specifieke manier) als u geen toegang hebt tot meer elegante oplossingen.


Antwoord 18

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

Antwoord 19

Dit werkt voor mij. Het spijt me als ik me de bron niet kan herinneren. Het komt waarschijnlijk van een man-pagina.

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

Antwoord 20

je kunt alle directe bestanden in je hoofdmap krijgen door std::experimental:: filesystem::directory_iterator() te gebruiken. Lees dan de naam van deze padbestanden.

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

Antwoord 21

Dit antwoord zou moeten werken voor Windows-gebruikers die problemen hebben gehad om dit te laten werken met Visual Studio met een van de andere antwoorden.

  1. Download het dirent.h-bestand van de github-pagina. Maar het is beter om gewoon het Raw dirent.h-bestand te gebruiken en mijn onderstaande stappen te volgen (zo heb ik het werkend gekregen).

    Github-pagina voor dirent.h voor Windows: Github-pagina voor dirent .h

    Raw Dirent-bestand: Raw dirent.h-bestand

  2. Ga naar je project en voeg een nieuw item toe (Ctrl+Shift+A). Voeg een headerbestand (.h) toe en noem het dirent.h.

  3. Plak het Onbewerkte dirent.h-bestandcodeer in je koptekst.

  4. Vermeld “dirent.h” in je code.

  5. Plaats de onderstaande void filefinder()-methode in uw code en roep deze aan vanuit uw main-functie of bewerk de functie zoals u deze wilt gebruiken.

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

Antwoord 22

Omdat bestanden en submappen van een map over het algemeen in een boomstructuur worden opgeslagen, is het een intuïtieve manier om het DFS-algoritme te gebruiken om elk ervan recursief te doorlopen.
Hier is een voorbeeld in het Windows-besturingssysteem met behulp van basisbestandsfuncties in io.h. U kunt deze functies in een ander platform vervangen. Wat ik wil zeggen, is dat het basisidee van DFS perfect aansluit bij dit probleem.

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

Antwoord 23

Ik heb geprobeerd het voorbeeld te volgen dat wordt gegeven in beideantwoordenen het is misschien de moeite waard om op te merken dat het lijkt alsof std::filesystem::directory_entryis gewijzigd in een overbelasting van de operator <<. In plaats van std::cout << p << std::endl;Ik moest het volgende gebruiken om te kunnen compileren en werken:

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

proberen palleen door te geven aan std::cout <<resulteerde in een ontbrekende overbelastingsfout.


Antwoord 24

Voortbouwend op wat herohuyongtao heeft gepost en een paar andere berichten:

http://www.cplusplus.com/forum/general/39766/

Wat is het verwachte invoertype van FindFirstFile?

Hoe converteer je wstring naar string?

Dit is een Windows-oplossing.

Omdat ik std::string wilde doorgeven en een vector van strings wilde retourneren, moest ik een paar conversies maken.

#include <string>
#include <Windows.h>
#include <vector>
#include <locale>
#include <codecvt>
std::vector<std::string> listFilesInDir(std::string path)
{
    std::vector<std::string> names;
    //Convert string to wstring
    std::wstring search_path = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(path);
    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)) 
            {
                //convert from wide char to narrow char array
                char ch[260];
                char DefChar = ' ';
                WideCharToMultiByte(CP_ACP, 0, fd.cFileName, -1, ch, 260, &DefChar, NULL);
                names.push_back(ch);
            }
        } 
        while (::FindNextFile(hFind, &fd));
        ::FindClose(hFind);
    }
    return names;
}

Antwoord 25

Gewoon iets dat ik wil delen en bedankt voor het leesmateriaal. Speel een beetje met de functie om het te begrijpen. Misschien vind je het leuk. e stond voor extensie, p is voor pad en s is voor padscheiding.

Als het pad wordt doorgegeven zonder een scheidingsteken dat eindigt, wordt er een scheidingsteken aan het pad toegevoegd. Voor de extensie, als een lege tekenreeks wordt ingevoerd, retourneert de functie elk bestand dat geen extensie in de naam heeft. Als een enkele ster is ingevoerd, worden alle bestanden in de map geretourneerd. Als e lengte groter is dan 0 maar geen enkele * is, dan wordt een punt toegevoegd aan e als e geen punt op de nulpositie had gehad.

Voor een terugkerende waarde. Als een kaart met lengte nul wordt geretourneerd, is er niets gevonden, maar was de map goed geopend. Als index 999 beschikbaar is vanaf de retourwaarde maar de kaartgrootte slechts 1 is, betekende dat dat er een probleem was met het openen van het directorypad.

Houd er rekening mee dat deze functie voor efficiëntie kan worden opgesplitst in 3 kleinere functies. Bovendien kunt u een oproepfunctie maken die op basis van de invoer detecteert welke functie deze gaat aanroepen. Waarom is dat efficiënter? Zei dat als je alles gaat pakken wat een bestand is, als je die methode doet, de subfunctie die is gebouwd voor het pakken van alle bestanden, gewoon alle bestanden zal pakken en geen andere onnodige voorwaarde hoeft te evalueren elke keer dat het een bestand heeft gevonden.

Dat is ook van toepassing wanneer u bestanden pakt die geen extensie hebben. Een specifiek gebouwde functie voor dat doel zou alleen het weer evalueren als het gevonden object een bestand is en vervolgens of de naam van het bestand een punt bevat.

De besparing is misschien niet veel als je alleen mappen leest met niet zo veel bestanden. Maar als u een grote hoeveelheid directory’s leest of als de directory een paar honderdduizenden bestanden bevat, kan dit een enorme besparing opleveren.

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

Antwoord 26

#include<iostream>
#include <dirent.h>
using namespace std;
char ROOT[]={'.'};
void listfiles(char* path){
    DIR * dirp = opendir(path);
    dirent * dp;
    while ( (dp = readdir(dirp)) !=NULL ) {
         cout << dp->d_name << " size " << dp->d_reclen<<std::endl;
    }
    (void)closedir(dirp);
}
int main(int argc, char **argv)
{
    char* path;
    if (argc>1) path=argv[1]; else path=ROOT;
    cout<<"list files in ["<<path<<"]"<<std::endl;
    listfiles(path);
    return 0;
}

Antwoord 27

Probeer scandir()van dirent.h

man scandir()


Antwoord 28

Op basis van de bovenstaande antwoorden

#include <vector>
#include <string>
#include <algorithm>
#ifdef _WIN32
#include <windows.h>
std::vector<std::string> files_in_directory(std::string path)
{
    std::vector<std::string> files;
    // check directory exists
    char fullpath[MAX_PATH];
    GetFullPathName(path.c_str(), MAX_PATH, fullpath, 0);
    std::string fp(fullpath);
    if (GetFileAttributes(fp.c_str()) != FILE_ATTRIBUTE_DIRECTORY)
        return files;
    // get file names
    WIN32_FIND_DATA findfiledata;
    HANDLE hFind = FindFirstFile((LPCSTR)(fp + "\\*").c_str(), &findfiledata);
    if (hFind != INVALID_HANDLE_VALUE)
    {
        do 
        {
            files.push_back(findfiledata.cFileName);
        } 
        while (FindNextFile(hFind, &findfiledata));
        FindClose(hFind);
    }
    // delete current and parent directories
    files.erase(std::find(files.begin(), files.end(), "."));
    files.erase(std::find(files.begin(), files.end(), ".."));
    // sort in alphabetical order
    std::sort(files.begin(), files.end());
    return files;
}
#else
#include <dirent.h>
std::vector<std::string> files_in_directory(std::string directory)
{
    std::vector<std::string> files;
    // open directory
    DIR *dir;
    dir = opendir(directory.c_str());
    if (dir == NULL)
        return files;
    // get file names
    struct dirent *ent;
    while ((ent = readdir(dir)) != NULL)
        files.push_back(ent->d_name);
    closedir(dir);
    // delete current and parent directories
    files.erase(std::find(files.begin(), files.end(), "."));
    files.erase(std::find(files.begin(), files.end(), ".."));
    // sort in alphabetical order
    std::sort(files.begin(), files.end());
    return files;
}
#endif  // _WIN32

Antwoord 29

Dit werkte voor mij. Het schrijft een bestand met alleen de namen (geen pad) van alle bestanden. Dan leest het dat txt-bestand en drukt het voor je af.

void DisplayFolderContent()
    {
        system("dir /n /b * > file_names.txt");
        char ch;
        std::fstream myStream("file_names.txt", std::fstream::in);
        while (myStream.get(ch))
        {
            std::cout << ch;
        }
    }

Other episodes