C++获取文件夹下所有文件名 _ filesystem库或dirent.h用法【详解】

阿辰吖_2334

阿辰吖_2334

2026-04-08

489人浏览

原创

std::filesystem 是当前 C++ 获取文件夹下所有文件名最可靠、跨平台的方式;dirent.h 仅限类 Unix 系统,Windows 下需额外兼容处理,不推荐新项目使用。

c++获取文件夹下所有文件名 _ filesystem库或dirent.h用法【详解】

用 std::filesystem 是当前 C++ 获取文件夹下所有文件名最可靠、跨平台的方式;dirent.h 仅限类 Unix 系统,Windows 下需额外兼容处理,不推荐新项目使用。

std::filesystem::directory_iterator 遍历目录(C++17 起)

这是标准、简洁、类型安全的做法。注意必须开启 C++17 或更高标准,且链接 stdc++fs(GCC)或确保 MSVC 版本支持(VS2019 v16.8+ 默认支持)。

常见错误现象:undefined reference to 'std::filesystem::directory_iterator::directory_iterator' —— 忘加链接选项;std::filesystem::directory_iterator 构造失败抛 std::filesystem::filesystem_error —— 路径不存在、无权限或不是目录。

  • 用 std::filesystem::is_regular_file() 过滤掉子目录(如只需文件名,不含子文件夹)
  • 用 entry.path().filename().string() 提取纯文件名(不含路径)
  • 若需递归遍历,请改用 std::filesystem::recursive_directory_iterator
  • 路径字符串建议用 std::filesystem::path 构造,避免手动拼接斜杠(/ vs )
#include <filesystem>
#include <iostream>
#include <vector><p>namespace fs = std::filesystem;</p>
<p>int main() {
std::vector<:string> filenames;
try {
for (const auto& entry : fs::directory_iterator("data/")) {
if (fs::is_regular_file(entry)) {
filenames.push_back(entry.path().filename().string());
}
}
} catch (const fs::filesystem_error& e) {
std::cerr </:string></p></vector></iostream></filesystem>

dirent.h 在 Linux/macOS 上的典型用法(非标准,不可跨平台)

dirent.h 是 POSIX 接口,Windows 原生不提供;MinGW 可模拟,但 MSVC 完全不支持(除非引入第三方头或改用 _findfirst)。它轻量但无类型检查,容易漏掉 . 和 .. 目录项。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

常见错误现象:readdir() returns NULL but no error set —— 忘记检查 errno;DT_DIR 判断在某些旧系统上不可靠;未跳过 . 和 .. 导致逻辑异常。

  • 必须包含 <dirent.h></dirent.h> 和 <sys></sys>(如需判断类型)
  • 用 stat() + S_ISREG() 判断是否为普通文件(d_type 字段在某些文件系统中不可靠)
  • 显式跳过 entry->d_name[0] == '.' 的条目(包括 . 和 ..)
  • 记得调用 closedir(),否则资源泄漏
#include <dirent.h>
#include <sys>
#include <vector>
#include <string><p>std::vector<:string> list_files_c(const char<em> path) {
std::vector<:string> names;
DIR</:string></em> dir = opendir(path);
if (!dir) return names;</:string></p>
<pre class="brush:php;toolbar:false;">struct dirent* entry;
while ((entry = readdir(dir)) != nullptr) {
    if (entry->d_name[0] == '.') continue; // skip . and ..
    std::string fullpath = std::string(path) + "/" + entry->d_name;
    struct stat st;
    if (stat(fullpath.c_str(), &st) == 0 && S_ISREG(st.st_mode)) {
        names.push_back(entry->d_name);
    }
}
closedir(dir);
return names;

}

Windows 下用 _findfirst/_findnext(仅 MSVC/MinGW 兼容)

这是 Windows 传统做法,比 dirent.h 更“原生”,但完全不可移植。结构体字段名(如 _finddata_t.name)和通配符语法(*.*)是硬编码习惯,容易写错。

常见错误现象:_findfirst 返回 -1 但没检查 errno;忘记用 _findclose();误把 _A_SUBDIR 当作文件类型标志(它只是属性位,需与 _A_NORMAL 组合判断)。

  • 搜索模式必须含通配符,例如 "data\*",不能只写 "data"
  • 用 file.attrib & _A_SUBDIR 判断是否为目录,而非直接比较 file.attrib == _A_SUBDIR
  • _findfirst 返回句柄,后续必须配对 _findnext + _findclose
  • 文件名字段是 file.name,不是 file.filename
#include <io.h>
#include <vector>
#include <string><p>std::vector<:string> list_files_win(const char<em> path) {
std::vector<:string> names;
std::string pattern = std::string(path) + "</:string></em>";
_finddata_t file;
intptr_t hFile = _findfirst(pattern.c_str(), &file);
if (hFile == -1) return names;</:string></p>
<pre class="brush:php;toolbar:false;">do {
    if (!(file.attrib & _A_SUBDIR)) { // not a directory
        names.push_back(file.name);
    }
} while (_findnext(hFile, &file) == 0);

_findclose(hFile);
return names;

}

真正要注意的是:std::filesystem 的路径对象在构造时会做规范化(如合并 ../),而 dirent.h 和 _findfirst 返回的都是原始目录项名称,不做路径解析。如果你依赖文件名顺序,std::filesystem::directory_iterator 不保证排序,需要手动 std::sort;而 readdir 和 _findnext 的顺序取决于文件系统底层,也不应假设有序。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

6139

3

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

2023.09.22

549

3

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

2024.03.01

1678

6

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

2023.09.04

1138

7

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.18

969

5

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.25

2840

5

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1698

5

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

2604

5

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

6024

49

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习