C语言打印CS50金字塔出现乱码与错位问题求助
CS50金字塔打印问题排查与修复
问题背景
重新学习CS50课程时,尝试实现一个金字塔打印任务:根据用户输入的高度(要求范围1-8),用#字符打印由左右两部分组成的金字塔,两部分之间空两格。比如高度为4时,正确输出如下:
# # ## ## ### ### #### ####
错误现象
程序在高度为1到7时运行正常,但设置高度为8时,金字塔左半部分的右侧会出现乱码的非ASCII字符。
问题代码
int main(void) { int h = 0; while (h < 1 || h > 8) { printf("Height: "); scanf("%d", &h); } for (int i = 0; i < h; i++) { char a[h + 1]; char b[h - (h - i) + 2]; for (int j = 0; j < h; j++) { a[j] = h - j > i + 1 ? ' ': '#'; if (i <= j) b[i] = '#'; } printf("%s %s\n", a, b); } }
无效尝试与新问题
一开始猜测是内存不足,把字符数组的大小改成3000后,乱码确实消失了,但当高度超过7时,金字塔出现了错位,输出变成这样:
# # ## ## ### ### #### #### ##### ##### ###### ###### ####### ####### ########
问题根源
核心问题是没有给字符数组添加字符串终止符\0:
- 在C语言里,
printf("%s")会从数组的起始位置开始读取数据,直到遇到\0才会停止输出。如果没有手动添加这个终止符,函数会继续读取数组后面的内存内容——这些都是未定义的垃圾数据,就会显示成乱码。 - 把数组改大到3000时,刚好后面的内存里有
\0,所以乱码消失了,但数组b的赋值逻辑本身有问题(始终给b[i]位置赋值,而不是对应每行的正确位置),导致了金字塔错位。
修复方法
在填充完字符数组的内容后,手动给数组加上字符串终止符\0,让printf能正确识别字符串的边界:
- 数组
a的长度是h+1,在索引h的位置添加a[h] = '\0' - 数组
b的有效长度是i+1(对应第i行的#数量),在索引i+1的位置添加b[i+1] = '\0'(原代码里的h - (h - i) +1其实等价于i+1)
修正后的正常代码
int main(void) { int h = 0; while (h < 1 || h > 8) { printf("Height: "); scanf("%d", &h); } for (int i = 0; i < h; i++) { char a[h + 1]; char b[h - (h - i) + 2]; for (int j = 0; j < h; j++) { a[j] = h - j > i + 1 ? ' ': '#'; if (i <= j) b[i] = '#'; } a[h] = '\0'; b[h - (h - i) + 1] = '\0'; printf("%s %s\n", a, b); } }
内容的提问来源于stack exchange,提问作者vaultdweller
相关产品推荐
相关产品推荐

