在 Linux 下使用 readdir(或更常见的 readdir() / readdir_r())读取目录时出现“乱码”,通常不是 readdir 本身的问题,而是字符编码或终端显示的问题。下面按常见原因给你梳理一下。
Linux 文件名是以字节序列存储的,readdir 返回的 d_name 也是字节数组,不关心编码。
如果:
C 或 GBK就会出现乱码。
locale
如果看到:
LANG=C
LC_ALL=C
那基本就是原因。
export LANG=zh_CN.UTF-8
export LC_ALL=zh_CN.UTF-8
或者临时测试:
LANG=en_US.UTF-8 ./your_program
示例:
printf("%s\n", entry->d_name);
这本身没问题,前提是终端编码和文件名编码一致。
如果你在 Windows 的串口工具(如旧版 SecureCRT、Putty 默认 GBK)访问 Linux,而文件名是 UTF-8,就会乱码。
✅ 解决:
有些文件是从 Windows、FTP、U盘拷贝过来的,文件名可能是:
readdir 如实返回,显示自然怪。
for (i = 0; d_name[i]; i++)
printf("%02x ", d_name[i]);
或用命令行:
ls | hexdump -C
struct dirent 中的:
char d_name[256];
只是原始字节,不是“字符串编码转换后的结果”。
如果你用:
wprintf都会出问题。
某些文件系统:
iocharset=gb2312挂载时可指定:
mount -o iocharset=utf8 /dev/sdb1 /mnt
#include <dirent.h>
#include <stdio.h>
int main() {
DIR *dir = opendir(".");
struct dirent *entry;
while ((entry = readdir(dir))) {
printf("%s\n", entry->d_name);
}
closedir(dir);
return 0;
}
只要:
就不会乱码。
locale 是不是 UTF-8如果你愿意,可以把:
locale 输出发出来,我可以精确告诉你到底是哪一步出的问题。