programing

C 또는 C++를 사용하여 디렉토리 내의 파일 목록을 가져오려면 어떻게 해야 합니까?

newsource 2022. 8. 8. 20:37

C 또는 C++를 사용하여 디렉토리 내의 파일 목록을 가져오려면 어떻게 해야 합니까?

C 코드 또는 C++ 코드 내부에서 디렉토리 내의 파일 목록을 판별하려면 어떻게 해야 합니까?

이 일을 할 수 .ls명령어를 사용하여 프로그램 내에서 결과를 구문 분석합니다.

업데이트 2017:

C++17 에서는, 파일 시스템의 파일을 일람 표시하는 공식 방법이 있습니다. std::filesystem다음의 소스 코드와 함께, Shrevardhan으로부터 훌륭한 회답변은 다음과 같습니다.

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

오래된 답변:

작고 간단한 작업에서는 boost를 사용하지 않고 derent.h를 사용합니다.UNIX에서는 표준 헤더로 사용할 수 있으며, Toni Ronko가 작성한 호환성 레이어를 통해 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;
}

이것은 단지 작은 헤더 파일일 뿐이며, 부스트와 같은 큰 템플릿 기반의 접근방식을 사용하지 않고 필요한 대부분의 간단한 작업을 수행할 수 있습니다.

C++17 에는, 다음과 같이 사용할 수 있는 가 있습니다.

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

또, 서브 디렉토리도 반복할 수 있습니다.

서드파티 라이브러리(Windows용)를 사용할 필요가 없기 때문에, 1개의 기능으로 충분합니다.

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

처럼 @Sebastian을 변경할 수 .*.*로로 합니다.*.ext특정 유형의 EXT 파일만 해당 디렉토리에 가져옵니다.

유감스럽게도 C++ 규격에서는 파일이나 폴더를 표준으로 취급하는 방법은 정의되어 있지 않습니다.

크로스 플랫폼 방식이 없기 때문에 가장 좋은 크로스 플랫폼 방식은 부스트 파일 시스템 모듈과 같은 라이브러리를 사용하는 것입니다.

크로스 플랫폼 부스트 방식:

다음 함수는 디렉토리 경로와 파일 이름을 지정하면 디렉토리와 하위 디렉토리에서 파일 이름을 재귀적으로 검색하여 bool을 반환하고, 성공한 경우 발견된 파일의 경로를 반환합니다.

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

위의 Boost 페이지에서 출처를 확인합니다.

Unix/Linux 기반 시스템의 경우:

opendir / readdir / closedir 를 사용할 수 있습니다.

디렉토리에서 "name" 항목을 검색하는 코드 예는 다음과 같습니다.

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;

위의 man 페이지의 소스 코드.

Windows 기반 시스템의 경우:

Win32 API Find First File / Find Next File / Find Close 함수를 사용할 수 있습니다.

다음 C++ 예는 Find First File을 최소한으로 사용하는 것을 나타내고 있습니다.

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

위의 msdn 페이지의 소스 코드.

C만의 솔루션에 대해서는, 이것을 확인해 주세요.추가 헤더만 있으면 됩니다.

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

다른 옵션에 비해 몇 가지 장점이 있습니다.

  • 포터블 - POSIX Drient와 Windows Find First File을 랩합니다.
  • it it를 한다.readdir_r는 스레드 스레드 세이프, 스레드 세이프, 스레드 세이프, 스레드 세이프, 스레드 세이프, 스레드 세이프, 스레드 세이프, 스레드 세이프, 스레드 라는 의미입니다.
  • 을 같은 UTF-16을 통해 합니다.UNICODE(마크로)
  • C90이므로 매우 오래된 컴파일러도 사용할 수 있습니다.

아래 스니펫을 사용하여 모든 파일을 나열할 수 있을 것 같습니다.

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

의) 입니다.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 */
};

를 사용하는 것을 추천합니다.glob이 재사용 가능한 포장지로요.「」가됩니다.vector<string>글로벌 패턴에 맞는 파일 경로에 대응합니다.

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

다음에, 다음과 같은 통상의 시스템 와일드 카드 패턴을 사용해 콜 할 수 있습니다.

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

.C++11를 사용합니다.boost::filesystem디렉토리내의 파일명을 취득하는 라이브러리(폴더명 제외):

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

출력은 다음과 같습니다.

file1.txt
file2.dat

'우리'를 쓰지 거죠?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;
}
#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;
}

쉬레바르단의 답변은 훌륭합니다. c하려면 c++14로 .namespace fs = experimental::filesystem;

예.,

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

시스템 호출!

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

그럼 그냥 파일을 읽어봐

편집: 이 답변은 해킹으로 간주해야 하지만, 보다 우아한 솔루션에 접근할 수 없는 경우에는 (플랫폼에 따라 다르지만) 실제로 효과가 있습니다.

x-플랫폼 방식의 부스트 시험

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

OS 고유의 파일만 사용할 수도 있습니다.

win32 api 를 win win win win win win win win win win win win win win win win win 。「를 지정해, 만 하면 .foldername을 '명부'라고 .getNextFile 것을 filename를 참조해 주세요.이 필요하다고 생각한다.windows.h ★★★★★★★★★★★★★★★★★」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;
    }

};

이 답변은 다른 답변과 함께 Visual Studio에서 작업하는 데 문제가 있는 Windows 사용자에게 적용됩니다.

  1. github 페이지에서 derent.h 파일을 다운로드합니다.다만, Raw derent.h 파일을 사용하고, 다음의 순서에 따라서 실행하는 것이 좋습니다(그것이, 내가 그것을 작동시킨 방법입니다).

    Windows 용 derent.h 의 Github 페이지:derent.h의 Github 페이지

    Raw Drient 파일: Raw Drient.h 파일

  2. 프로젝트로 이동하여 새 아이템 추가(+)CtrlShiftA헤더 파일(.h)을 추가하고 이름을 derent.h로 지정합니다.

  3. Raw drient.h 파일코드를 헤더에 붙여넣습니다.

  4. "다이어트"를 포함합니다.h" 를 입력합니다.

  5. 를 넣으세요.void filefinder() 및 calling의 합니다.main기능을 편집하거나 사용할 기능을 편집합니다.

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

이 실장에서는, 지정한 디렉토리의 컨텐츠로 문자열 배열을 동적으로 채우는 것으로 목적을 실현합니다.

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

영웅후용타오가 올린 글과 다른 글들을 바탕으로:

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

Find First File에서 예상되는 입력 유형은 무엇입니까?

wstring을 문자열로 변환하는 방법

이것은 Windows 솔루션입니다.

std:: 문자열을 전달하고 문자열 벡터를 반환하고 싶었기 때문에 몇 가지 변환을 해야 했습니다.

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

는 bothanswer에서 주어진 예를 따르려고 노력했고 그것이 마치 다음과 같이 보인다는 것을 주목할 가치가 있을 것이다.std::filesystem::directory_entry has has has has of of of of of of of of of of of of of of of of of of of of of of of가 가 되지 않도록 되었습니다.<< of instead instead.std::cout << p << std::endl;컴파일과 동작을 하기 위해서는 다음 사항을 사용해야 했습니다.

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

통과하려고 노력하다를 통과시키려고 하고p그 독학을 저절로 하다std::cout <<실종된 과부하 오류에 심증.과부하누락 오류가 발생했습니다.

std::experimental:: filesystem::directory_iterator 를 사용하면 루트 디렉토리에 있는 모든 파일을 가져올 수 있습니다.그런 다음 이러한 경로 파일의 이름을 읽습니다.

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

일반적으로 디렉토리의 파일 및 하위 디렉토리는 트리 구조에 저장되므로 직관적인 방법은 DFS 알고리즘을 사용하여 각 디렉토리를 재귀적으로 통과하는 것입니다.다음은 io.h의 기본 파일 기능을 사용한 Windows 운영 체제의 예입니다.이러한 기능은 다른 플랫폼에서 교환할 수 있습니다.제가 표현하고 싶은 것은 DFS의 기본 개념은 이 문제를 완벽하게 충족한다는 것입니다.

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

난 이거면 돼.출처가 기억나지 않는다면 죄송합니다.그것은 아마 man페이지에서 온 것 같다.

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

이 코드가 도움이 되길 바랍니다.

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

이건 나한테 효과가 있었어.모든 파일의 이름(경로 없음)만으로 파일을 씁니다.그런 다음 txt 파일을 읽고 인쇄해 줍니다.

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

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

Cesar Alejandro Montero Orozco의 답변에 기고합니다.

에는 아름다움의 단순성, 그심플함에 아름다움이 있습니다를 첨가하여에 있다.그리고 그 심플함에는/s주요, 우리는 또한 하위 디렉터리를 통과한다.키,서브디렉토리도 조사합니다.

system("dir /n /b /s * > file_names.txt");

GNU 매뉴얼 FTW

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

또한 소스(펀 의도)로 바로 이동하는 것이 좋을 수 있습니다.Linux에서 가장 일반적인 명령어의 내부를 보면 많은 것을 알 수 있습니다.GNU의 coreutils의 간단한 미러를 github에 설정했습니다(읽기용).

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

이것은 Windows 를 대상으로 하고 있지 않을지도 모르지만, 이러한 방법을 사용하면, Unix 의 변종을 사용하는 많은 케이스가 있습니다.

도움이 됐으면 좋겠는데...

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

제가 공유하고 싶은 것, 그리고 읽어주셔서 감사합니다.기능을 조금 더 가지고 놀면 이해할 수 있습니다.e는 extension, p는 path, s는 path separator를 나타냅니다.

경로가 종료 구분 기호 없이 전달되면 구분 기호가 경로에 추가됩니다.확장자의 경우 빈 문자열을 입력하면 이름에 확장자가 없는 파일이 반환됩니다.별 하나가 입력된 경우 디렉토리 내의 모든 파일이 반환됩니다.e 길이가 0보다 크지만 단일 *이 아닌 경우 e에 0 위치에 점이 포함되지 않은 경우 e 앞에 점이 추가됩니다.

반환값의 경우.길이 0의 맵이 반환된 경우 디렉토리는 정상적으로 열려 있었지만 아무것도 발견되지 않았습니다.반환값에서 인덱스999를 사용할 수 있지만 맵사이즈가 1밖에 되지 않는 경우 디렉토리 경로를 여는 데 문제가 있음을 의미합니다.

효율성을 위해 이 기능은 3개의 작은 기능으로 나눌 수 있습니다.또, 입력에 근거해 콜 하는 함수를 검출하는 발신자 함수를 작성할 수 있습니다.왜 그게 더 효율적일까요?파일의 모든 것을 취득하는 경우, 그 방법을 사용하면, 모든 파일을 취득하기 위해서 작성된 서브 함수는, 모든 파일을 취득할 수 있기 때문에, 파일을 검출할 때마다 그 외의 불필요한 조건을 평가할 필요는 없습니다.

확장자가 없는 파일을 가져올 때도 해당됩니다.이 목적을 위한 특정 빌드 함수는 발견된 객체가 파일일 경우에만 날씨를 평가하고 파일 이름에 점이 있는지 여부를 평가합니다.

파일이 많지 않은 디렉토리만 읽으면 절약 효과가 크지 않을 수 있습니다.그러나 대량의 디렉토리를 읽고 있거나 디렉토리에 수십만 개의 파일이 있는 경우에는 큰 절약이 될 수 있습니다.

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

트라이 해라scandir()부터에서dirent.h

man scandir()

상기의 회답에 근거하고 있습니다.

#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

언급URL : https://stackoverflow.com/questions/612097/how-can-i-get-the-list-of-files-in-a-directory-using-c-or-c