遍历c++中的所有目录和子目录



我想使用std::filesystem::recursive_directory_iterator类创建一个遍历所有子目录并处理找到的xml文件的类方法。

我在网上找到的唯一方法是使用像这样的for循环:

for (fs::directory_entry p : fs::recursive_directory_iterator("my_file"))
do_something(p);

问题是我需要在函数调用之间存储我的迭代器(或至少它指向的地方),因为我一次只能处理一个文件。我试着这样实现它:

class C {
private:
std::filesystem::recursive_directory_iterator it;
std::filesystem::directory_entry p;
public:
C(std::filesystem::path);
std::string find_file();
};
C::C(std::filesystem::path path)
{
it = fs::recursive_directory_iterator(path);
p = fs::directory_entry(it.begin());
}
std::string C::find_file()
{
do { //using do while so my function won't load the same file twice
++p;
} while (!is_xml(p.path()) && p != it.end());
}

std::filesystem::recursive_directory_iterator似乎没有begin()end()的方法,无法比较。

我不知道我的代码与for range循环有什么不同,除了存储迭代器和有一个额外的条件。

如果您查看std::filesystem::recursive_directory_iterator非成员函数,您可以看到:

// range-based for loop support
begin(std::filesystem::recursive_directory_iterator)
end(std::filesystem::recursive_directory_iterator)

然后std::filesystem::begin(recursive_directory_iterator), std::filesystem::end(recursive_directory_iterator)有更多的细节:

end(recursive_directory_iterator)返回默认构造的recursive_directory_iterator,用作结束迭代器。参数被忽略。

检查it是否不等于std::end(it),看看是否还有其他元素。你必须增加it,而不是p

你还需要检查it != std::end(it)是否在你做!is_xml(*it.path())之前

std::string C::find_file()
{
do { //using do while so my function won't load the same file twice
++it;
} while (it != std::end(it) && !is_xml(*it.path()));
}

recursive_directory_iterator本身已经是一个迭代器(它的名字就说明了这一点),所以您根本不需要使用begin()end()。它实现了operator==,operator!=,operator->operator++,这是您在这种情况下所需要的。

同样,根本没有理由让p成为类成员。它应该是find_file()的一个局部变量(实际上,在这种情况下,它可以完全消除)。并且循环应该是while循环而不是do..while循环,以防迭代器已经在它的"end"当输入find_file()时。

试试这个:

class C {
private:
std::filesystem::recursive_directory_iterator it;
public:
C(std::filesystem::path);
std::string find_file();
};
C::C(std::filesystem::path path)
: it(path)
{
}
std::string C::find_file()
{
static std::filesystem::directory_iterator end;
while (it != end) {
auto p = it->path();
if (is_xml(p))
return p.string();
++it;
}
return "";
}

最新更新