温馨提示×

ubuntu readdir为何乱码

小樊
55
2026-09-21 20:42:06
栏目: 智能运维

在 Ubuntu(Linux)下使用 readdir 读取目录时出现“乱码”,通常不是 readdir 本身的问题,而是编码不一致或使用方式不当导致的。下面按常见原因逐条说明。


一、最常见原因:文件名编码不是 UTF-8

现象

  • 中文文件名显示成 ????、方块、奇怪字符
  • ls 正常,但程序里乱码

原因

Linux 默认使用 UTF-8 编码文件名,但如果:

  • 文件名是在 Windows(GBK / GB2312)下创建的
  • U 盘、NTFS / FAT 文件系统
  • 老系统或非中文 UTF-8 环境

那么 readdir 返回的 d_name 就是 非 UTF-8 字节流,直接当 UTF-8 打印就会乱码。

验证

locale
file 某个文件

解决

  1. 确保终端和程序使用 UTF-8
export LANG=zh_CN.UTF-8
export LC_ALL=zh_CN.UTF-8
  1. 如果是 GBK 文件名,需要转码(C/C++):
#include <iconv.h>
// GBK -> UTF-8

二、终端编码不对

现象

  • readdir 没问题,但 printf 出来乱码
  • ls 也乱码

解决

终端设置为 UTF-8:

  • GNOME Terminal:右键 → 编码 → UTF-8
  • 或:
locale

确保不是 C 或 POSIX


三、错误地把 d_name 当宽字符处理

错误示例

wprintf(L"%s", ent->d_name); // 错

正确示例

printf("%s\n", ent->d_name);

d_name 是 char*,不是 wchar_t*


四、文件系统本身编码问题(NTFS / FAT)

原因

  • Windows 下 U 盘常用 GBK
  • Linux 挂载时未指定编码

解决(挂载时)

mount -o iocharset=utf8 /dev/sdb1 /mnt

或 /etc/fstab:

/dev/sdb1 /mnt vfat iocharset=utf8 0 0

五、readdir 返回的是“原始字节”,不是字符串

重点

readdir 不会解码文件名,它返回的是:

文件系统在磁盘上存储的原始字节

所以:

  • 程序必须自己知道编码
  • 不能假设一定是 UTF-8

六、示例代码(安全用法)

#include <dirent.h>
#include <stdio.h>

int main() {
    DIR *dir = opendir(".");
    struct dirent *ent;
    while ((ent = readdir(dir))) {
        printf("%s\n", ent->d_name);
    }
    closedir(dir);
}

只要:

  • 终端 UTF-8
  • 文件名 UTF-8 就不会乱码

七、快速自检清单

✅ locale 是 UTF-8
✅ 终端编码 UTF-8
✅ 文件名是 UTF-8
✅ 没用 wchar 错误打印
✅ 非 Windows 文件系统未错挂


如果你愿意,可以贴:

  • 你的 C / C++ 代码
  • locale 输出
  • 乱码截图或字符

我可以直接帮你定位是哪一层出的问题。

0 踩