You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 14:03:20