Jak Mogę uzyskać listę plików w katalogu używając C lub c++?

Jak mogę określić listę plików w katalogu z mojego kodu C lub c++?

Nie wolno mi wykonywać polecenia ls i analizować wyników z mojego programu.

Author: samoz, 2009-03-04

24 answers

W małych i prostych zadaniach nie używam boost, używam dirent.h , który jest również dostępny dla windows:

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

Jest to tylko mały plik nagłówkowy i wykonuje większość prostych rzeczy, których potrzebujesz, bez użycia dużego podejścia opartego na szablonach, takiego jak boost (bez obrazy, Lubię boost!).

Autorem warstwy zgodności windows jest Toni Ronkko. W systemie Unix jest to standardowy nagłówek.

Aktualizacja 2017:

W C++17 jest teraz oficjalny sposób na listę plików Twój system plików: std::filesystem. Jest doskonała odpowiedź od Shreevardhan poniżej z tym kodem źródłowym:

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

int main()
{
    std::string path = "/path/to/directory";
    for (auto & p : fs::directory_iterator(path))
        std::cout << p << std::endl;
}
Rozważ poprawienie jego odpowiedzi, jeśli używasz podejścia C++17.
 634
Author: Peter Parker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-14 09:51:47

Niestety standard C++ nie definiuje standardowego sposobu pracy z plikami i folderami w ten sposób.

Ponieważ nie ma sposobu cross platform, najlepszym sposobem cross platform jest użycie biblioteki, takiej jak boost filesystem module .

Metoda Cross platform boost:

Następująca funkcja, biorąc pod uwagę ścieżkę katalogu i nazwę pliku, rekurencyjnie przeszukuje katalog i jego podkatalogi pod kątem nazwy pliku, zwracając bool i jeśli się powiedzie, ścieżka do pliku, który został znaleziony.

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

Źródło z wyżej wymienionej strony boost.


Dla systemów Unix / Linux:

Możesz użyć opendir / readdir / closedir .

Przykładowy kod, który przeszukuje katalog w poszukiwaniu wpisu "nazwa" to:

   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;

Kod źródłowy z powyższych stron podręcznika.


Dla systemów opartych na systemie windows:

Możesz użyć Win32 API FindFirstFile / FindNextFile / funkcje FindClose .

Poniższy przykład C++ pokazuje minimalne użycie pliku 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);
   }
}

Kod źródłowy z powyższych stron msdn.

 213
Author: Brian R. Bondy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-29 20:30:42

C++17 ma teraz std::filesystem::directory_iterator, które mogą być używane jako

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

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

Także, std::filesystem::recursive_directory_iterator może również iterować podkatalogi.

 191
Author: Shreevardhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-19 17:04:50

wystarczy jedna funkcja, nie musisz używać żadnej biblioteki innej firmy (Dla Windows).

#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: jak wspomniał @Sebastian, możesz zmienić *.* na *.ext, aby uzyskać tylko pliki EXT (tj. określonego typu) w tym katalogu.

 75
Author: herohuyongtao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-12 04:35:40

Dla rozwiązania Tylko C, sprawdź to. Wymaga tylko dodatkowego nagłówka:

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

Niektóre zalety nad innymi opcjami:

    [12]}jest przenośny - otacza POSIX dirent i Windows FindFirstFile
  • używa readdir_r, jeśli jest dostępny, co oznacza, że jest (zwykle) threadsafe
  • obsługuje Windows UTF-16 poprzez te same makra UNICODE
  • jest to C90, więc nawet bardzo starożytne Kompilatory mogą go używać
 44
Author: congusbongus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-17 07:37:37

Zalecam użycie glob z tym opakowaniem wielokrotnego użytku. Generuje vector<string> odpowiadające ścieżkom plików pasującym do wzorca glob:

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

, które można następnie wywołać za pomocą zwykłego schematu wieloznacznego systemu, takiego jak:

vector<string> files = globVector("./*");
 26
Author: Chris Redford,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-13 13:40:28

Oto bardzo prosty kod w C++11 za pomocą biblioteki boost::filesystem, aby uzyskać nazwy plików w katalogu (z wyłączeniem nazw katalogów):

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

Wyjście wygląda następująco:

file1.txt
file2.dat
 19
Author: Bad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-25 16:51:30

Dlaczego nie użyć 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;
}
 17
Author: Meekohi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-15 15:03:46

Myślę, że poniższy fragment może być użyty do listy wszystkich plików.

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

Poniżej znajduje się struktura STRUCT dirent

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 */
};
 15
Author: Shrikant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-26 11:17:48

Try boost for X-platform method

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

Lub po prostu użyj swoich plików specyficznych dla systemu operacyjnego.

 10
Author: Tim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-04 19:37:54

Sprawdź tę klasę, która używa API win32. Po prostu zbuduj instancję, podając foldername, z którego chcesz listę, a następnie wywołaj metodę getNextFile, aby uzyskać następną filename z katalogu. Myślę, że potrzebuje windows.h i 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
Author: robertvarga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-25 06:40:40

GNU Manual FTW

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

Również, czasami dobrze jest przejść od razu do źródła (kalambur zamierzony). Możesz się wiele nauczyć, patrząc na wnętrzności niektórych z najczęstszych poleceń w Linuksie. Skonfigurowałem proste lustro coreutils GNU na GitHubie (do czytania).

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

Maybe this nie odnosi się do systemu Windows, ale wiele przypadków użycia wariantów Uniksa można mieć za pomocą tych metod.

Mam nadzieję, że to pomoże...

 6
Author: Homer6,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-11 21:35:12
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
Author: JasonYen2205,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-29 21:12:31

Mam nadzieję, że ten kod ci pomoże.

#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
Author: Yas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-19 18:22:37

Ta implementacja realizuje twój cel, dynamicznie wypełniając tablicę łańcuchów zawartością podanego katalogu.

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
Author: Giacomo Marciani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-13 15:08:17

To mi pasuje. Przepraszam, jeśli nie pamiętam źródła. Prawdopodobnie pochodzi ze strony podręcznika.

#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
Author: ENHering,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-22 04:44:07

Odpowiedź Shreevardhan działa świetnie. Ale jeśli chcesz go używać w c++14 po prostu dokonaj zmiany namespace fs = experimental::filesystem;

Tzn.,

#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
Author: Venkat Vinay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-13 06:38:01

Możesz uzyskać wszystkie bezpośrednie pliki w katalogu głównym za pomocą STD::experimental:: filesystem::directory_iterator(). Następnie przeczytaj nazwę tych plików ścieżek.

#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
Author: ducPham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-20 18:04:35

System call it!

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

Następnie po prostu przeczytaj plik.

EDIT: ta odpowiedź powinna być uważana za hack, ale naprawdę działa (choć w sposób specyficzny dla platformy), jeśli nie masz dostępu do bardziej eleganckich rozwiązań.

 1
Author: Catalyst,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-15 04:51:12

Ta odpowiedź powinna działać dla użytkowników systemu Windows, którzy mieli problemy z uzyskaniem tej pracy z Visual Studio z którąkolwiek z innych odpowiedzi.

  1. Pobierz dirent.plik h ze strony github. Ale lepiej jest po prostu użyć surowego dirent.plik h i wykonaj moje kroki poniżej (tak dostałem go do pracy).

    Strona Github dla dirent.h Dla Windows: strona Github dla dirent.h

    Raw Dirent File: Raw dirent.plik h

  2. Idź do swojego projekt i dodanie nowego elementu (Ctrl+Shift+A ). Dodaj plik nagłówka (.h) i nazwać go dirent.h.

  3. Wklej surowy dirent.h plik Kod do nagłówka.

  4. Include " dirent.h " w Twoim kodzie.

  5. Umieść poniższą metodę void filefinder() w swoim kodzie i wywołaj ją z funkcji main lub edytuj funkcję w jaki sposób chcesz jej użyć.

    #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
Author: ZKR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-04 00:49:01

Ponieważ pliki i podkatalogi katalogu są zazwyczaj przechowywane w strukturze drzewa, intuicyjnym sposobem jest użycie algorytmu DFS do rekurencyjnego przemierzania każdego z nich. Oto przykład w systemie operacyjnym windows przy użyciu podstawowych funkcji plików w io.H. możesz zastąpić te funkcje na innej platformie. To, co chcę wyrazić, to to, że podstawowa idea DFS doskonale spełnia ten problem.

#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
Author: tkingcer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-11 06:57:30

Starałem się podążać za przykładem podanym w ZARÓWNO odpowiedzi {[8] } i warto zauważyć, że wygląda na to, że std::filesystem::directory_entry został zmieniony, aby nie mieć przeciążenia operatora <<. Zamiast std::cout << p << std::endl; musiałem użyć poniższego, aby móc skompilować i uruchomić:

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

Próba przejścia p samodzielnie do std::cout << spowodowała brakujący błąd przeciążenia.

 0
Author: StarKiller4011,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-25 14:50:54

Po prostu coś, czym chcę się podzielić i dziękuję za lekturę materiału. Pobaw się funkcją, aby ją zrozumieć. Może Ci się spodoba. e oznacza rozszerzenie, p oznacza ścieżkę, A s oznacza separator ścieżek.

Jeśli ścieżka zostanie przekazana bez zakończenia separatora, do ścieżki zostanie dołączony separator. W przypadku rozszerzenia, jeśli wprowadzony jest pusty łańcuch znaków, funkcja zwróci dowolny plik, który nie ma rozszerzenia w swojej nazwie. Jeśli jedna gwiazda została wprowadzona niż wszystkie pliki w katalogu zostaną zwrócone. Jeśli długość e jest większa niż 0, ale nie jest pojedynczą *, to kropka będzie poprzedzona E, jeśli e nie zawierała kropki w pozycji zerowej.

Dla zwracanej wartości. Jeśli zwrócona jest mapa o zerowej długości, to nic nie zostało znalezione, ale katalog był otwarty w porządku. Jeśli indeks 999 jest dostępny od zwracanej wartości, ale rozmiar mapy wynosi tylko 1, oznacza to, że wystąpił problem z otwarciem ścieżki katalogu.

Zauważ, że dla efektywności, to funkcję można podzielić na 3 mniejsze funkcje. Ponadto możesz utworzyć funkcję wywołującą, która wykryje, którą funkcję będzie wywoływać na podstawie danych wejściowych. Dlaczego to jest bardziej efektywne? Powiedział, że jeśli masz zamiar chwycić wszystko, co jest plikiem, robiąc tę metodę, podfunkcja, która została zbudowana do chwytania wszystkich plików, po prostu chwyci wszystkie pliki i nie musi oceniać żadnego innego niepotrzebnego warunku za każdym razem, gdy znalazł plik.

To również dotyczy, gdy zbieraj pliki, które nie mają rozszerzenia. Specjalna funkcja do tego celu będzie oceniać pogodę tylko wtedy, gdy znaleziony obiekt jest plikiem, a następnie czy w nazwie pliku znajduje się kropka.

Zapis może nie być zbyt duży, jeśli czytasz tylko katalogi zawierające nie tyle plików. Ale jeśli czytasz masową ilość katalogu lub jeśli katalog ma kilkaset tysięcy plików, może to być ogromna oszczędność.

#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
Author: Kevin Ng,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-01 00:10:23

To mi pomogło. Zapisuje plik zawierający tylko nazwy (bez ścieżki) wszystkich plików. Następnie odczytuje ten plik txt i drukuje go dla Ciebie.

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

    }
 -1
Author: Cesar Alejandro Montero Orozco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-28 05:23:35