在 Ubuntu(Linux)下使用 opendir() 函数时,有几个常见的注意点和坑,下面按使用流程 + 易错点说明:
#include <dirent.h>
#include <stdio.h>
DIR *dir = opendir("/path/to/dir");
if (dir == NULL) {
perror("opendir");
return -1;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
closedir(dir);
#include <dirent.h>
#include <sys/types.h> // 通常 dirent.h 已包含,但写上更稳妥
否则可能报:
implicit declaration of function 'opendir'
if (dir == NULL) {
perror("opendir");
}
常见失败原因:
opendir("test.txt"); // ❌ 错误
如果是文件,opendir 返回 NULL,errno = ENOTDIR
. 和 .. 要处理if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0)
continue;
否则会:
opendir → readdir → closedir
忘记 closedir() 会:
readdir() 不是线程安全readdir_r(dir, entry, &result);
或使用 readdir + 加锁
if (entry->d_type == DT_REG) { ... }
注意:
d_type == DT_UNKNOWNstat()char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s", dir_path, entry->d_name);
避免:
gcc dir.c -o dir
不需要额外链接库(libc 默认)
| 问题 | 原因 |
|---|---|
| Segmentation fault | 未判 opendir == NULL |
| 死循环 | 没跳过 . / .. |
| 打开失败 | 权限不够 / SELinux / 路径错 |
| 递归爆栈 | 深度过大或未过滤符号链接 |
S_ISLNK)getdents()(底层)std::filesystem(C++17)如果你愿意,可以告诉我:
我可以给你一份可直接用的完整示例。