如何使用C或C++获取目录中的文件列表?

如何从我的C或C++代码中确定目录中的文件列表?

我不允许执行ls命令并从我的程序中解析结果。

1196687 次浏览

尝试提升x平台方法

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

或者只是使用您的操作系统特定文件的东西。

不幸的是,C++标准没有定义以这种方式处理文件和文件夹的标准方式。

由于没有跨平台的方式,最好的跨平台方式是使用Boost文件系统模块之类的库。

跨平台Boost方式:

以下函数,给定目录路径和文件名,递归搜索目录及其子目录的文件名,返回一个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;
}

来自上面提到的提升页面。

对于基于Unix/Linux系统:

您可以使用opendir/readdir/沉积物

在目录中搜索条目“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;

源代码来自上面的手册页。

对于基于Windows的系统:

您可以使用Win32 API搜索结果/查找下一个文件/查找关闭函数。

下面的C++示例向您展示了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);
}
}

源代码来自上面的msdn页面。

2017年更新

在C++17中,现在有一种正式的方法来列出文件系统的文件:std::filesystem。下面的Shree vardhan有一个很好的答案,包含以下源代码:

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

旧答案:

在小型和简单的任务中,我不使用提升,我使用dirent. h。它可作为UNIX中的标准标头使用,也可通过兼容性层由Toni Ronkko创建用于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;
}

它只是一个小头文件,可以完成您需要的大部分简单工作,而无需使用基于模板的大型方法,如提升(无意冒犯,我喜欢提升!)。

看看这个使用win32 api的类。只需通过提供您想要列表的foldername来构建一个实例,然后调用getNextFile方法从目录中获取下一个filename。我认为它需要windows.hstdio.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;
}


};

我希望这个代码可以帮助你。

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

GNU手册FTW

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

此外,有时直接找到源代码是很好的(双关语)。您可以通过查看Linux中一些最常见命令的内部内容学到很多东西。我在github上设置了一个GNU coreutils的简单镜像(供阅读)。

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

也许这并不能解决Windows问题,但可以通过使用这些方法来使用Unix变体的许多情况。

希望这能帮助…

对于仅限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 dirent和Windows FindFirstFile
  • 它在可用的情况下使用readdir_r,这意味着它(通常)是线程安全的
  • 通过相同的UNICODE宏支持Windows UTF-16
  • 它是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 */
};

一个函数就足够了,你不需要使用任何第三方库(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:正如@Sebastian所提到的,您可以将*.*更改为*.ext,以便仅获取该目录中的EXT文件(即特定类型的文件)。

为什么不使用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;
}

系统叫它!

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

然后只读文件。

编辑:这个答案应该被认为是一个黑客,但如果你不能访问更优雅的解决方案,它确实有效(尽管是以特定于平台的方式)。

我建议将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("./*");

此实现实现了您的目的,用指定目录的内容动态填充字符串数组。

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

这是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

C++17现在有一个std::filesystem::directory_iterator,它可以用作

#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也可以迭代子目录。

这对我有用。如果我不记得来源,我很抱歉。它可能来自一个手册页。

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

这对我很有效。它只用所有文件的名称(没有路径)写入一个文件。然后它读取那个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;
}


}

Shreevardhan的回答很有效。但是如果你想在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;
}

由于目录的文件和子目录通常存储在树形结构中,一种直观的方法是使用DFS算法递归遍历它们中的每一个。 下面是一个在windows操作系统中使用io. h中的基本文件函数的例子。你可以在其他平台上替换这些函数。我想表达的是,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);
}

您可以使用std::experimental:: 文件系统::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;
}

此答案应该适用于无法将此与Visual Studio一起使用任何其他答案的Windows用户。

  1. 从github页面下载dirent. h文件。但最好只使用Raw dirent. h文件并按照我下面的步骤操作(这就是我如何让它工作的)。

    适用于Windows的dirent. h的Github页面:dirent. h的github页面

    原始不同文件:原始dirent. h文件

  2. 转到您的项目并添加一个新项目(Ctrl+Shift+A)。添加一个头文件(. h)并将其命名为dirent. h。

  3. 粘贴原始dirent. h文件代码到你的头。

  4. 在您的代码中包含“dirent. h”。

  5. 将下面的void filefinder()方法放入您的代码中,并从您的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);
    }
    

我试图遵循两者答案中给出的示例,可能值得注意的是,似乎std::filesystem::directory_entry已更改为没有<<运算符的重载。而不是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 <<会导致丢失的重载错误。

只是我想分享的东西,感谢你的阅读材料。玩一下这个函数来理解它。你可能会喜欢它。e代表扩展,p代表路径,s代表路径分隔符。

如果路径没有结束分隔符,分隔符将被附加到路径。对于扩展名,如果输入空字符串,则该函数将返回其名称中没有扩展名的任何文件。如果输入单个星形,则将返回目录中的所有文件。如果e长度大于0但不是单个*,则如果e在零位置不包含点,则将在e之前添加一个点。

对于返回值。如果返回一个零长度的map,则没有找到任何内容,但目录打开正常。如果返回值中索引999可用,但map大小仅为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;
}

基于Herhuyongtao发布的内容和其他一些帖子:

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

FindFirstFile的预期输入类型是什么?

如何将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;
}
#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;
}

dirent.h尝试scandir()

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

Shreevardhan的设计也适用于遍历子目录:

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


using namespace std;
namespace fs = filesystem;
int main()
{
string path = "\\path\\to\\directory";
// string path = "/path/to/directory";
for (auto & p : fs::recursive_directory_iterator(path))
cout << p.path() << endl;
}

编译:cl /EHsc /W4 /WX /std:c++17 ListFiles.cpp

Cesar Alejandro Montero Orozco的回答的贡献。

简单中有美,通过添加/s键,我们还会遍历子目录。

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

简单地在Linux使用下面的ASCI C风格代码

#include <bits/stdc++.h>
#include <dirent.h>
using namespace std;


int main(){
DIR *dpdf;
struct dirent *epdf;
dpdf = opendir("./");
    

if (dpdf != NULL){
while (epdf = readdir(dpdf)){
cout << epdf->d_name << std::endl;
}
}
closedir(dpdf);
return 0;
}

希望这有帮助!

Peter Parker的解决方案,但不使用for:

#include <algorithm>
#include <filesystem>
#include <ranges>
#include <vector>


using namespace std;


int main() {
vector<filesystem::path> filePaths;
ranges::transform(filesystem::directory_iterator("."),
back_inserter(filePaths), [](const auto& dirFile){return dirFile.path();} );
}