C语言垂直直方图实现:星号排版间距异常问题求助
核心问题分析
你的代码存在三个关键问题,直接导致垂直直方图排版错误:
- 数组越界访问
- 单词计数逻辑的条件判断错误(误用赋值运算符而非比较运算符)
- 垂直直方图的打印逻辑完全偏离需求
具体调试建议
1. 修复数组越界问题
C语言数组是0索引起始,你定义的worldlengths[MAXWORDLENGTH](MAXWORDLENGTH=10)仅能访问索引0~9,但你循环时用了i=1到10,这会访问数组外的内存,触发未定义行为。
修正方案:将数组定义为int worldlengths[MAXWORDLENGTH + 1];,这样索引110都合法,和你统计的单词长度(110)直接对应。
2. 修复单词计数的条件判断错误
代码中else if (state = OUT)是赋值操作(把OUT赋值给state),不是比较操作,这会导致每次进入该分支都会强制将state设为OUT,进而错误触发单词计数逻辑。
修正方案:把=改成比较运算符==,即else if (state == OUT)。
3. 重构垂直直方图的打印逻辑
你当前的打印循环逻辑完全错误,垂直直方图需要按行打印:
- 先找到所有单词长度计数的最大值(确定直方图的最高行数)
- 从最高行到第1行,逐行遍历每个单词长度列:
- 如果该列的计数 ≥ 当前行高度,打印
*(带空格的格式化星号) - 否则打印
(占位空格)
- 如果该列的计数 ≥ 当前行高度,打印
- 每行打印完后换行,最后再打印横坐标(单词长度)和对应计数。
修正后的完整代码
#include <stdio.h> #define IN 1 /* In a word */ #define OUT 0 /* Out of word */ #define MAXWORDLENGTH 10 /* Maximum word length */ int main() { // 标准C要求main返回int类型 int c = 0, i = 0, j = 0, state = OUT, letters = 0; int max_count = 0; // 记录直方图的最大高度 int ovflow = 0; // 统计长度超标的单词数量 int worldlengths[MAXWORDLENGTH + 1]; // 修正数组长度,支持1~10索引 // 初始化数组所有元素为0 for (i = 0; i <= MAXWORDLENGTH; i++) { worldlengths[i] = 0; } // 统计单词长度 while ((c = getchar()) != EOF && c != 'q') { // 合并退出条件,逻辑更简洁 if (c == ' ' || c == '\t' || c == '\n') { state = OUT; if (letters > 0) { if (letters <= MAXWORDLENGTH) { worldlengths[letters]++; // 更新最大计数,用于确定直方图高度 if (worldlengths[letters] > max_count) { max_count = worldlengths[letters]; } } else { ovflow++; } letters = 0; } } else if (state == OUT) { // 修正为比较运算符 state = IN; letters = 1; // 单词开始,计数初始化为1 } else { letters++; // 单词中,计数递增 } } // 处理循环结束时未统计的最后一个单词 if (letters > 0) { if (letters <= MAXWORDLENGTH) { worldlengths[letters]++; if (worldlengths[letters] > max_count) { max_count = worldlengths[letters]; } } else { ovflow++; } } // 打印垂直直方图 for (i = max_count; i >= 1; i--) { for (j = 1; j <= MAXWORDLENGTH; j++) { if (worldlengths[j] >= i) { printf("* "); } else { printf(" "); } } putchar('\n'); } // 打印横坐标(单词长度) for (i = 1; i <= MAXWORDLENGTH; i++) { printf("%2d ", i); } putchar('\n'); // 打印每个长度对应的单词数量 for (i = 1; i <= MAXWORDLENGTH; i++) { printf("%2d ", worldlengths[i]); } putchar('\n'); // 打印超长单词统计结果 if (ovflow > 0) { printf("\n有 %d 个单词长度超过%d\n", ovflow, MAXWORDLENGTH); } return 0; // 标准C要求main返回值 }
额外优化说明
- 补充了标准C要求的
main函数返回值定义和返回语句 - 合并了退出条件(EOF和输入'q'),逻辑更简洁
- 增加了循环结束时未统计单词的处理,避免最后一个单词丢失计数
- 新增了超长单词的统计输出,完善功能
内容的提问来源于stack exchange,提问作者user23465972
相关产品推荐
相关产品推荐

