C语言读取txt文件统计字符频率时重音字符识别错误如何解决
问题根因
你碰到的是编码不匹配问题:
- 你的
prueba.txt是UTF-8编码,西语带重音字符(比如á)在UTF-8里是多字节存储的,á对应的UTF-8字节序列就是0xC3 0xA1(也就是你读到的195、161) - 你代码里写的判断值是Latin1(ISO-8859-1)编码下的字符值,和UTF-8的字节序列完全不匹配,自然识别失败。
解决方案
方案1:快速适配现有代码(修改文件编码)
如果不想大改现有逻辑,直接把待处理的txt文件另存为ISO-8859-1(也叫Latin1、西欧编码)格式即可,这种编码下所有西语字符(包括带重音字符、ñ)都是单字节存储,你只需要调整对应字符的判断值和实际编码对应就行。比如Latin1下的小写á是0xE1(225),大写Á是0xC1(193),对应加到字母a的计数里即可。
方案2:直接处理UTF-8编码文件(更通用)
如果要保留原文件的UTF-8编码,可以用宽字符接口处理,核心逻辑参考如下:
#include <stdio.h> #include <wchar.h> #include <wctype.h> #include <locale.h> int main(){ setlocale(LC_ALL, "es_ES.UTF-8"); // 适配西语UTF-8环境 wint_t c; FILE *file = fopen("prueba.txt", "r"); int letters[27] = {0}; if (file){ while ((c = fgetwc(file)) != WEOF) { // 先统一转小写再判断,简化分支逻辑 wint_t lower_c = towlower(c); switch(lower_c) { case L'a': case L'á': letters[0]++; break; case L'b': letters[1]++; break; case L'c': letters[2]++; break; case L'd': letters[3]++; break; case L'e': case L'é': letters[4]++; break; // 依次补全f到h的对应判断 case L'i': case L'í': letters[8]++; break; // 依次补全j到n的对应判断 case L'ñ': letters[26]++; break; // 依次补全o到t的对应判断 case L'o': case L'ó': letters[14]++; break; case L'u': case L'ú': case L'ü': letters[20]++; break; // 其他非目标字符直接忽略 default: break; } } fclose(file); } // 后续自行补充计数结果输出逻辑 return 0; }
注意:Windows环境下如果宽字符接口不生效,可以先把控制台编码设置为UTF-8,或者用轻量第三方UTF-8解析库手动拼接多字节序列后再做判断。
内容的提问来源于stack exchange,提问作者Mari
相关产品推荐
相关产品推荐

