如何用C语言读取UTF-8文本文件并统计各字符的出现频次
问题排查
- 你现有代码的核心问题是默认按单字节处理字符,而UTF-8为变长编码,∮、→、∞这类特殊字符以及中文都占2-4字节,逐字节读取对比会把完整字符拆成多个乱码片段,无法正确识别统计。
- 其次fgets循环会反复覆盖
data缓冲区,仅保留文件最后一行的内容,前面读取的内容全部丢失,统计范围不完整。 - 50字节的缓冲区长度过小,承载多字节字符时极易发生溢出,引发未知错误。
修复后可实现UTF-8字符统计的代码
#include <stdio.h> #include <wchar.h> #include <locale.h> #include <stdbool.h> #define MAX_CHAR_COUNT 1024 // 可根据实际文本字符数调整 int main() { // 启用系统UTF-8本地化支持 setlocale(LC_ALL, ""); FILE *fp = fopen("test.txt", "r"); if (fp == NULL) { printf("文件打开失败\n"); return 1; } wint_t ch; wchar_t unique_chars[MAX_CHAR_COUNT] = {0}; int count[MAX_CHAR_COUNT] = {0}; int unique_len = 0; // 逐字符读取,自动识别UTF-8多字节字符转为宽字符 while ((ch = fgetwc(fp)) != WEOF) { // 不需要统计换行可保留此行,需要统计换行直接删除即可 if (ch == L'\n') continue; bool exists = false; // 检查是否已经统计过该字符 for (int i = 0; i < unique_len; i++) { if (unique_chars[i] == ch) { count[i]++; exists = true; break; } } // 新增未统计过的字符 if (!exists && unique_len < MAX_CHAR_COUNT) { unique_chars[unique_len] = ch; count[unique_len] = 1; unique_len++; } } fclose(fp); // 输出统计结果 wprintf(L"字符频次统计结果:\n"); for (int i = 0; i < unique_len; i++) { wprintf(L"%lc->%d\n", unique_chars[i], count[i]); } return 0; }
注意事项
- 运行前需确保你的系统已配置UTF-8编码环境,test.txt文件保存为UTF-8编码格式即可正常识别所有UTF-8字符。
- 如果需要统计的字符总量超过1024,自行调整
MAX_CHAR_COUNT宏的数值即可。
内容的提问来源于stack exchange,提问作者Phat Phat
相关产品推荐
相关产品推荐

