遍历c ++中的所有目录和子目录
iterating through all the directories and subdirectories in c++
我想使用 std::filesystem::recursive_directory_iterator
class 创建一个 class 方法遍历所有子目录并处理找到的 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()
的方法,无法比较
除了存储迭代器和具有额外条件外,我不知道我的代码与工作范围循环有何不同。
如果你看 std::filesystem::recursive_directory_iterator Non-member functions 你会发现有:
// range-based for loop support
begin(std::filesystem::recursive_directory_iterator)
end(std::filesystem::recursive_directory_iterator)
end(recursive_directory_iterator)
Returns a default-constructed recursive_directory_iterator, which serves as the end iterator. The argument is ignored.
所以你会检查it
是否不等于std::end(it)
,所以看看有没有更多的元素。而且你必须增加 it
而不是 p
.
您还需要在执行 !is_xml(*it.path())
之前检查是否 it != std::end(it)
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
根本没有理由成为 class 成员。应该改成find_file()
的局部变量(其实这种情况下完全可以去掉)。并且循环应该是 while
循环而不是 do..while
循环,以防输入 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 "";
}
我想使用 std::filesystem::recursive_directory_iterator
class 创建一个 class 方法遍历所有子目录并处理找到的 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()
的方法,无法比较
除了存储迭代器和具有额外条件外,我不知道我的代码与工作范围循环有何不同。
如果你看 std::filesystem::recursive_directory_iterator Non-member functions 你会发现有:
// range-based for loop support
begin(std::filesystem::recursive_directory_iterator)
end(std::filesystem::recursive_directory_iterator)
end(recursive_directory_iterator)
Returns a default-constructed recursive_directory_iterator, which serves as the end iterator. The argument is ignored.
所以你会检查it
是否不等于std::end(it)
,所以看看有没有更多的元素。而且你必须增加 it
而不是 p
.
您还需要在执行 !is_xml(*it.path())
it != std::end(it)
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
根本没有理由成为 class 成员。应该改成find_file()
的局部变量(其实这种情况下完全可以去掉)。并且循环应该是 while
循环而不是 do..while
循环,以防输入 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 "";
}