使用 std::filesystem::directory_iterator 遍历当前目录的一级子目录最简洁可靠,C++17 起标准支持,自动跳过 . 和 ..,需显式调用 is_directory() 判断,无需递归且轻量高效。

用 std::filesystem::directory_iterator 遍历当前目录的子目录
直接用 std::filesystem 是最简洁可靠的方式,C++17 起标准支持,不用依赖 Boost 或系统 API。它会自动跳过 . 和 ..,也天然区分文件和目录。
关键点:必须显式检查每个 entry 是否为目录,不能只靠名字判断;迭代器默认不递归,正合你“只取一级子目录”的需求。
- 确保编译器开启 C++17(如 g++ 加
-std=c++17) - 链接时若报 undefined reference,Windows MSVC 一般没问题,GCC/Clang 可能需加
-lstdc++fs -
std::filesystem::current_path()返回的是绝对路径,但directory_iterator接收相对路径(如".")也完全合法
#include <filesystem>
#include <vector>
#include <string>
std::vector<std::string> getSubdirs() {
std::vector<std::string> result;
for (const auto& entry : std::filesystem::directory_iterator(".")) {
if (entry.is_directory()) {
result.push_back(entry.path().filename().string());
}
}
return result;
}
为什么不用 std::filesystem::recursive_directory_iterator
它会钻进所有嵌套子目录,一层层往下走,结果里混着孙子、曾孙级目录,不符合“当前目录的子目录”这个限定。除非你手动记录深度并提前 break,但那就绕远了,还容易出错。
- 如果你真需要限制深度,得自己维护一个计数器,每次
entry.depth()> 1 就跳过 —— 但directory_iterator更轻量、更直白 -
recursive_directory_iterator构造开销略大,尤其目录树深时,没必要
Windows 下路径分隔符和编码坑
返回的 entry.path().filename().string() 在 Windows 上是 UTF-8 编码(MSVC 默认),但控制台可能用 GBK 显示乱码;Linux/macOS 一般无感。
立即学习“C++免费学习笔记(深入)”;
- 如果后续要拼路径(比如打开子目录里的文件),建议保留
std::filesystem::path类型,别急着转std::string—— 它能正确处理/和\ - 避免用
c_str()直接传给旧 C API(如opendir()),跨平台时易挂 - 若必须输出中文名到控制台,Windows 上可临时调用
SetConsoleOutputCP(CP_UTF8)(仅限 cmd/powershell)
替代方案:opendir/readdir 的兼容性代价
纯 C 方式(<dirent.h></dirent.h>)在 Linux/macOS 上没问题,但 Windows 不原生支持,得额外引入兼容层(如 mingw 的实现或自己封装)。而且它不区分文件/目录类型,得再调 stat() 判断,代码更啰嗦、错误分支更多。
- 除非项目强制要求 C++11 或更低标准,否则没理由退回去
-
readdir返回的d_name是裸 char*,没 RAII,忘了closedir就泄漏句柄 - 跨平台构建时,
dirent.h头文件位置、函数签名可能不一致,CI 容易翻车
undefined reference to std::filesystem::...,不是代码错,是漏了 -lstdc++fs 或没设 C++17。



















