在 CentOS 系统中,如果使用 readdir
函数读取目录时遇到中文乱码问题,通常是因为文件名编码与系统默认编码不匹配。以下是一些解决方法:
确保系统的 locale 设置正确,特别是 LANG
和 LC_ALL
变量。你可以通过以下命令检查和设置:
# 检查当前 locale 设置
locale
# 设置 locale 为 UTF-8
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
为了使这些设置在每次登录时生效,可以将它们添加到你的 shell 配置文件中(例如 .bashrc
或 .bash_profile
):
echo 'export LANG=en_US.UTF-8' >> ~/.bashrc
echo 'export LC_ALL=en_US.UTF-8' >> ~/.bashrc
source ~/.bashrc
iconv
转换编码如果你从文件系统中读取的文件名是其他编码(例如 GBK),可以使用 iconv
工具将其转换为 UTF-8 编码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <iconv.h>
char* convert_encoding(const char* inbuf, size_t inlen, const char* from_charset, const char* to_charset) {
iconv_t cd = iconv_open(to_charset, from_charset);
if (cd == (iconv_t)-1) {
perror("iconv_open");
return NULL;
}
size_t outbuf_size = inlen * 4; // 足够大的缓冲区
char* outbuf = malloc(outbuf_size);
if (!outbuf) {
perror("malloc");
iconv_close(cd);
return NULL;
}
char* inptr = (char*)inbuf;
char* outptr = outbuf;
size_t inbytesleft = inlen;
size_t outbytesleft = outbuf_size;
if (iconv(cd, &inptr, &inbytesleft, &outptr, &outbytesleft) == (size_t)-1) {
perror("iconv");
free(outbuf);
iconv_close(cd);
return NULL;
}
*outptr = '\0'; // 确保字符串以 null 结尾
iconv_close(cd);
return outbuf;
}
int main() {
DIR* dir = opendir(".");
if (!dir) {
perror("opendir");
return EXIT_FAILURE;
}
struct dirent* entry;
while ((entry = readdir(dir)) != NULL) {
char* utf8_name = convert_encoding(entry->d_name, strlen(entry->d_name), "GBK", "UTF-8");
if (utf8_name) {
printf("%s
", utf8_name);
free(utf8_name);
} else {
printf("Failed to convert name: %s
", entry->d_name);
}
}
closedir(dir);
return EXIT_SUCCESS;
}
mbstowcs
和 wcstombs
转换编码如果你更喜欢使用 C 标准库函数,可以使用 mbstowcs
和 wcstombs
进行编码转换:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <locale.h>
int main() {
setlocale(LC_ALL, ""); // 设置 locale 为当前环境
DIR* dir = opendir(".");
if (!dir) {
perror("opendir");
return EXIT_FAILURE;
}
struct dirent* entry;
while ((entry = readdir(dir)) != NULL) {
wchar_t wide_name[PATH_MAX];
mbstowcs(wide_name, entry->d_name, PATH_MAX);
char utf8_name[PATH_MAX];
wcstombs(utf8_name, wide_name, PATH_MAX);
printf("%s
", utf8_name);
}
closedir(dir);
return EXIT_SUCCESS;
}
通过以上方法,你应该能够解决 CentOS 系统中使用 readdir
读取目录时遇到的中文乱码问题。