C语言字母计数程序仅统计'a'无法遍历a-z的问题修复
问题原因
原代码只能统计'a'的核心原因是输入流读取逻辑完全写反:
- 第一轮循环j=1匹配字符'a'时,内层
while ((c[f] = getchar()) != EOF)会把所有输入一次性读到EOF,输入流直接被读空。等j递增到2开始匹配'b'时,已经没有任何输入内容可读,后续字母的匹配逻辑自然完全不生效。
除此之外还有几个逻辑错误:
- 代码里的
b[i] + j;是无效表达式,计算结果没有赋值给任何变量,根本不会生成存储a-z的字符序列 - 只用了单个
counter变量存储计数,无法独立保存26个字母的出现次数,就算输入流正常,后续字母的计数也会和'a'的计数累加,结果错误 - 最外层
for (int i = 0; i < 1; ++i)循环无实际意义,仅会执行1次 - 长度为10的
c数组完全多余,逐字符读取判断时不需要缓存批量字符,反而容易出现数组越界问题
修复方案
不需要提前生成a-z字符数组再逐轮匹配输入,直接利用ASCII码的连续特性,单次遍历输入即可完成全字母计数:
- 定义长度为26的整型数组作为计数器,每个元素对应一个小写字母的计数,初始值全为0
- 逐字符读取输入,每读到一个字符就判断是否为小写a-z:如果是,就用字符值减去'a'得到0-25的下标,对应给计数器数组的元素加1
- 所有输入读取完成后,遍历计数器数组,逐个输出每个字母的出现次数
修复后的可运行代码:
#include <stdio.h> int main() { int counter[26] = {0}; int ch; // 单次遍历读取所有输入,边读边计数 while ((ch = getchar()) != EOF) { if (ch >= 'a' && ch <= 'z') { // 直接通过ASCII偏移计算对应计数器下标 counter[ch - 'a']++; } } // 输出所有字母的统计结果 for (int i = 0; i < 26; i++) { printf("%c = %d\n", 'a' + i, counter[i]); } return 0; }
注:如果需要同时统计大写字母,可以在判断分支里加对应大写字母的偏移逻辑,统一转成小写计数或者分开计数即可。
内容的提问来源于stack exchange,提问作者INDIAN KNIGHT
相关产品推荐
相关产品推荐

