我决定再次学习 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。它停止打印乱码,并且对于高度 1 - 7 仍然可以正常工作,但是当用户放置超过 7 的任何内容时,金字塔看起来像这样倾斜:
#
# ##
## ###
### ####
#### #####
##### ######
###### #######
####### ########
为什么会发生这种情况以及如何解决?
您的代码似乎没有什么问题。
您正在循环内初始化数组 a 和 b。这意味着每次迭代都会创建不同大小的数组,从而导致不可预测的行为。
当您使用 %s 打印数组时,它需要以 null 结尾的字符串。但是,数组 a 和 b 可能不是以 null 终止的。 要解决此问题,您可以修改代码以对每行使用单个数组并调整打印逻辑。尝试以下代码:
#include <stdio.h>
int main(void) {
int h = 0;
while (h < 1 || h > 8) {
printf("Height: ");
scanf("%d", &h);
}
for (int i = 0; i < h; i++) {
char row[2 * h + 3]; // Maximum required size for the row
for (int j = 0; j < 2 * h + 2; j++) {
if (j < h - i || (j >= h && j < h + 2) || j > h + i + 1) {
row[j] = ' ';
} else {
row[j] = '#';
}
}
row[2 * h + 2] = '\0'; // Null-terminate the string
printf("%s\n", row);
}
返回0; }