如何使用 std::filesystem::path 对象遍历目录并过滤特定后缀?

在 C++17 之后,<filesystem> 标头为文件系统操作提供了强大的工具。本文将演示如何使用 std::filesystem::path 以及相关 API 进行目录遍历,并针对特定文件后缀(如 .cpp.h)进行过滤。目标是编写一个简洁、可移植且易维护的代码片段,并说明关键点和常见陷阱。


1. 环境准备

首先确保编译器支持 C++17 或更高版本,并已启用 `

` 标头。对于 GCC 9+、Clang 10+ 和 MSVC 19.14+,只需添加 `-std=c++17` 或 `-std=c++20` 即可。 “`bash g++ -std=c++20 -O2 -Wall -Wextra main.cpp -o scan_dir “` — ## 2. 代码结构概览 “`cpp #include #include #include #include namespace fs = std::filesystem; // 1. 递归遍历目录 std::vector find_files(const fs::path& root, const std::vector& suffixes); // 2. 主函数演示 int main() { std::vector extensions = {“.cpp”, “.h”, “.hpp”}; auto files = find_files(“src”, extensions); std::cout std::vector find_files(const fs::path& root, const std::vector& suffixes) { std::vector result; if (!fs::exists(root) || !fs::is_directory(root)) return result; std::unordered_set suffix_set(suffixes.begin(), suffixes.end()); try { for (const auto& entry : fs::recursive_directory_iterator(root, fs::directory_options::skip_permission_denied)) { if (entry.is_regular_file()) { auto ext = entry.path().extension().string(); // std::filesystem uses case-sensitive comparison by default. // Convert to lower-case if needed for case-insensitive matching. if (suffix_set.count(ext)) { result.push_back(entry.path()); } } } } catch (const fs::filesystem_error& e) { std::cerr #include std::string to_lower(const std::string& s) { std::string r = s; std::transform(r.begin(), r.end(), r.begin(), [](unsigned char c){ return std::tolower(c); }); return r; } std::vector find_files_ci(const fs::path& root, const std::vector& suffixes) { std::vector result; if (!fs::exists(root) || !fs::is_directory(root)) return result; std::unordered_set suffix_set; for (auto s : suffixes) suffix_set.insert(to_lower(s)); try { for (const auto& entry : fs::recursive_directory_iterator(root, fs::directory_options::skip_permission_denied)) { if (entry.is_regular_file()) { auto ext = to_lower(entry.path().extension().string()); if (suffix_set.count(ext)) result.push_back(entry.path()); } } } catch (const fs::filesystem_error& e) { std::cerr

发表评论