提问人:Calabran 提问时间:8/9/2023 更新时间:8/9/2023 访问量:100
在 C++ 中抛出异常后,如何继续 for 循环的下一次迭代?
How do I continue to the next iteration of a for loop after an exception is thrown in C++?
问:
我正在尝试用于遍历我的 C 驱动器和打印文件路径,但我一直遇到以下异常:std::filesystem::recursive_directory_iterator
terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error' what(): filesystem error: cannot increment recursive directory iterator: Invalid argument
我试过:
#include <iostream>
#include <filesystem>
int main() {
for (auto const& dir_entry : std::filesystem::recursive_directory_iterator("C:\\")) {
try {
std::cout << dir_entry << std::endl;
} catch (std::filesystem::__cxx11::filesystem_error) {
continue;
}
}
return 0;
}
我原以为它会在遇到异常后继续进行下一次迭代,但我只是收到了相同的错误消息。
我也试过:
#include <iostream>
#include <filesystem>
int main() {
try {
for (auto const& dir_entry : std::filesystem::recursive_directory_iterator("C:\\")) {
std::cout << dir_entry << std::endl;
}
} catch (std::filesystem::__cxx11::filesystem_error) {
std::cout << "Ran into exception";
}
return 0;
}
它抓住了问题并执行了块,但我无法继续下一次迭代,因为语句在循环之外。catch
try/catch
for
答:
您无法继续执行下一个迭代,因为没有下一个迭代。
无法递增递归目录迭代器
如果出现其他异常,您的第一个代码片段可能会起作用,但这个代码片段将不允许继续迭代。
这里有一个解决方法。
#include <iostream>
#include <filesystem>
int main(int argc, char** argv)
{
if(argc < 1)
return 1;
for(std::filesystem::recursive_directory_iterator i {argv[1]}, saved, end;
i != end; ) {
std::cout << *i << '\n';
saved = i;
try {
++i;
} catch(std::filesystem::filesystem_error& err) {
std::cout << "Error: " << err.what() << '\n';
i = std::move(saved);
i.disable_recursion_pending();
++i;
}
}
}
基本上,您可以将迭代器保存在副本中,然后禁用递归。据我所知,至少对于 GCC,复制迭代器只是复制 a 和 a .这意味着它不是真正的副本,但由于在引发异常时不会修改共享状态,因此这有效。基本上,我们只需要确保当迭代器在异常后将自身重置为状态时,共享状态不会被丢弃。shared_ptr
bool
end
当然,更好的选择是设置skip_permission_denied
标志。但有时您可能想知道是否存在没有权限的目录。那么我认为这是最好的选择。或者,您可以先在不使用迭代器的情况下探测每个目录,看看是否可以读取它,然后在需要时调用它。disable_recursion_pending
评论