如何使用C++在Windows中列出子目录?最好使用可跨平台运行的代码。
这是我针对这个问题的解决方案,但它只适用于Windows操作系统。我希望能够使用跨平台的解决方案,但不想使用boost。
#include <Windows.h>
#include <vector>
#include <string>
/// Gets a list of subdirectories under a specified path
/// @param[out] output Empty vector to be filled with result
/// @param[in] path Input path, may be a relative path from working dir
void getSubdirs(std::vector<std::string>& output, const std::string& path)
{
WIN32_FIND_DATA findfiledata;
HANDLE hFind = INVALID_HANDLE_VALUE;
char fullpath[MAX_PATH];
GetFullPathName(path.c_str(), MAX_PATH, fullpath, 0);
std::string fp(fullpath);
hFind = FindFirstFile((LPCSTR)(fp + "\\*").c_str(), &findfiledata);
if (hFind != INVALID_HANDLE_VALUE)
{
do
{
if ((findfiledata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0
&& (findfiledata.cFileName[0] != '.'))
{
output.push_back(findfiledata.cFileName);
}
}
while (FindNextFile(hFind, &findfiledata) != 0);
}
}
/// Gets a list of subdirectory and their subdirs under a specified path
/// @param[out] output Empty vector to be filled with result
/// @param[in] path Input path, may be a relative path from working dir
/// @param[in] prependStr String to be pre-appended before each result
/// for top level path, this should be an empty string
void getSubdirsRecursive(std::vector<std::string>& output,
const std::string& path,
const std::string& prependStr)
{
std::vector<std::string> firstLvl;
getSubdirs(firstLvl, path);
for (std::vector<std::string>::iterator i = firstLvl.begin();
i != firstLvl.end(); ++i)
{
output.push_back(prependStr + *i);
getSubdirsRecursive(output,
path + std::string("\\") + *i + std::string("\\"),
prependStr + *i + std::string("\\"));
}
}
这个解决方案相对较好,并且应该可以跨平台使用。您需要更改代码中希望执行某些操作的部分,但除此之外,它应该可以很好地工作。
#include <cstring>
#include <io.h>
#include <iostream>
#include <stdio.h>
using namespace std;
void list(char* dir)
{
char originalDirectory[_MAX_PATH];
// Get the current directory so we can return to it
_getcwd(originalDirectory, _MAX_PATH);
_chdir(dir); // Change to the working directory
_finddata_t fileinfo;
// This will grab the first file in the directory
// "*" can be changed if you only want to look for specific files
intptr_t handle = _findfirst("*", &fileinfo);
if(handle == -1) // No files or directories found
{
perror("Error searching for file");
exit(1);
}
do
{
if(strcmp(fileinfo.name, ".") == 0 || strcmp(fileinfo.name, "..") == 0)
continue;
if(fileinfo.attrib & _A_SUBDIR) // Use bitmask to see if this is a directory
cout << "This is a directory." << endl;
else
cout << "This is a file." << endl;
} while(_findnext(handle, &fileinfo) == 0);
_findclose(handle); // Close the stream
_chdir(originalDirectory);
}
int main()
{
list("C:\\");
return 0;
}
这是非常简洁的代码,将列出目录中的所有子目录和文件。如果您想要它列出每个子目录中的所有内容,您可以通过在打印“这是一个目录”行时传递子目录来递归调用该函数。类似于list(fileinfo.name)应该能解决问题。
WIN32_FIND_DATA.dwFileAttributes
部分,以获取FILE_ATTRIBUTE_DIRECTORY
值,以检查结果是否为目录。此外,你还应该检查.
和..
,因为它们也作为结果返回。 - avee从2022年开始使用
std::filesystem::directory_iterator
#include <filesystem>
using namespace std::filesystem;
path sandbox = "sandbox";
create_directories(sandbox/"dir1"/"dir2");
// directory_iterator can be iterated using a range-for loop
for (auto const& dir_entry : directory_iterator{sandbox}){
if(dir_entry.is_directory()){ //checking if dir or file.
std::cout << dir_entry << '\n';
}
}
std::filesystem::recursive_directory_iterator
这个功能用于一次性遍历所有嵌套的子目录。
https://en.cppreference.com/w/cpp/filesystem/directory_iterator