C语言柱状图程序问题:特定输入下输出与预期不符
C语言柱状图程序输出异常修复
问题描述
需要实现一个C语言柱状图程序,规则如下:
- 允许输入最多20个[-10,10]区间的整数,输入
999终止输入 - 若输入非
999且超出区间,输出提示并终止程序 - 柱状图用
|、*、-绘制:列由对应数值长度的|组成,末尾替换为*;列间留两个空格;绘制零水平线,零值元素在该线用*标记
当前程序在多数场景下输出正常,但输入序列10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10时,输出与预期不符。
原代码
#include <math.h> #include <stdio.h> #include <stdlib.h> int main() { int niz[20], i, j, k, brojac = 0, visina = 0, sirina = 0, max = 0, min = 0; char matrica[50][50]; int imaasteriks[50] = {0}; printf("Unesite clanove niza: \n"); for (i = 0; i < 20; i++) { scanf("%d", &niz[i]); if (niz[i] == 999) { break; } else if (niz[i] > 10 || niz[i] < -10) { printf("Broj nije u trazenom intervalu"); return 0; } brojac++; } for (i = 0; i < 50; i++) { for (j = 0; j < 50; j++) { matrica[i][j] = ' '; } } for (i = 0; i < brojac; i++) { if (niz[i] > max) { max = niz[i]; } if (niz[i] < min) { min = niz[i]; } } visina = 1 + abs(max) + abs(min); sirina = 2 * brojac + brojac; for (k = 0; k < brojac; k++) { for (j = 3 * k; j < 3 * k + 3; j++) { for (i = 0; i < visina; i++) { if (i == max) { if (niz[k] == 0 && imaasteriks[k] == 0) { matrica[i][j] = '*'; imaasteriks[k] = 1; } else if (j == 3 * k) { matrica[i][j] = '-'; } else { matrica[i][j] = '-'; } } else if (niz[k] > 0) { if (j == k * 3 && i == max - niz[k]) { matrica[i][j] = '*'; } else if (i > max - niz[k] && j == 3 * k && i < max) { matrica[i][j] = '|'; } else { matrica[i][j] = ' '; } } else if (niz[k] < 0) { if (i == max - niz[k] && j == k * 3) { matrica[i][j] = '*'; } else if (i < max - niz[k] && i > max && j == 3 * k) { matrica[i][j] = '|'; } else { matrica[i][j] = ' '; } } else if (j != k * 3 && i != max) { matrica[i][j] = ' '; } } } } for (i = 0; i < visina; i++) { for (j = 0; j < sirina; j++) { printf("%c", matrica[i][j]); } printf("\n"); } return 0; }
当前输出
* | * | | * | | | * | | | | * | | | | | * --------------------*----------------------------- ---------- * | | | | | | | | | | | * | | | | | | | | | | * | | | | | | | | | * | | | | | | | | * | | | | | | | * | | | | | | * | | * | | * | * | *
预期输出
* | * | | * | | | * | | | | * | | | | | * | | | | | | * | | | | | | | * | | | | | | | | * | | | | | | | | | * ------------------------------*----------------------------- * | | | | | | | | * | | | | | | | * | | | | | | * | | | | | * | | | | * | | | * | | * | *
问题分析与修复
错误点1:数组容量不足
原代码中niz数组大小为20,无法容纳用户输入的21个元素,导致最后一个元素-10被截断。将数组大小调整为21以匹配输入需求。
错误点2:零水平线绘制逻辑错误
原代码按每个柱子的局部范围绘制横线,导致线条不连续且左侧缺失。正确做法是先将整个零水平线(i = max的行)全部设为-,再将零值元素的位置替换为*。
错误点3:负数柱子的范围判断错误
原代码中负数柱子的|范围条件逻辑混乱,导致柱子位置颠倒。正确的范围应为:从零水平线下方(i = max + 1)开始,到max + abs(niz[k]) - 1为|,max + abs(niz[k])位置为*。
错误点4:循环顺序导致的覆盖问题
原代码在同一循环中混合处理零水平线和柱子绘制,可能导致已绘制的柱子被覆盖。调整为先绘制零水平线,再分别绘制正、负柱子。
修复后的代码
#include <math.h> #include <stdio.h> #include <stdlib.h> int main() { // 调整数组大小以容纳21个元素 int niz[21], i, j, k, brojac = 0, visina = 0, sirina = 0, max = 0, min = 0; char matrica[50][50]; printf("Unesite clanove niza: \n"); for (i = 0; i < 21; i++) { scanf("%d", &niz[i]); if (niz[i] == 999) { break; } if (niz[i] > 10 || niz[i] < -10) { printf("Broj nije u trazenom intervalu"); return 0; } brojac++; } // 初始化画布为空格 for (i = 0; i < 50; i++) { for (j = 0; j < 50; j++) { matrica[i][j] = ' '; } } // 计算最大值和最小值 for (i = 0; i < brojac; i++) { if (niz[i] > max) { max = niz[i]; } if (niz[i] < min) { min = niz[i]; } } visina = 1 + abs(max) + abs(min); sirina = 3 * brojac; // 每个元素占1字符+2空格,总宽度3*元素数 // 绘制零水平线 for (j = 0; j < sirina; j++) { matrica[max][j] = '-'; } // 替换零值位置为* for (k = 0; k < brojac; k++) { if (niz[k] == 0) { matrica[max][3 * k] = '*'; } } // 绘制正数柱子 for (k = 0; k < brojac; k++) { if (niz[k] > 0) { int start = max - niz[k]; // 顶部的* matrica[start][3 * k] = '*'; // 中间的| for (i = start + 1; i < max; i++) { matrica[i][3 * k] = '|'; } } } // 绘制负数柱子 for (k = 0; k < brojac; k++) { if (niz[k] < 0) { int len = abs(niz[k]); int end = max + len; // 底部的* matrica[end][3 * k] = '*'; // 中间的| for (i = max + 1; i < end; i++) { matrica[i][3 * k] = '|'; } } } // 输出画布 for (i = 0; i < visina; i++) { for (j = 0; j < sirina; j++) { printf("%c", matrica[i][j]); } printf("\n"); } return 0; }
内容的提问来源于stack exchange,提问作者Irma Ibrović
相关产品推荐
相关产品推荐

