C语言马里奥金字塔程序输入验证问题求助
搞定马里奥金字塔的输入验证问题
嘿,我来帮你捋清楚输入验证的门道,再排查你代码里的问题!
先讲输入验证的核心原理
输入验证可不是只检查数字范围这么简单,得两步走:
- 第一步:确保输入的是合法的数据类型:你要的是整数,那得先确认用户输入的真的是整数,而不是字母、符号或者乱七八糟的东西。如果用户输入了非整数,
scanf("%d")会直接失败,不会修改你的height变量,而且这些错误的输入会留在输入缓冲区里,下次调用scanf还会读这些垃圾,直接导致死循环。 - 第二步:验证数据的范围:这部分你已经做了——检查输入的整数是否在0到23之间,没问题。
你的代码里的问题
咱们来看你的代码:
// Prompt user till input is 0-23 do { printf("Welcome to Mario Pyramid Builder! Enter a number from 0 - 23: "); scanf("%d", &height); if(height >= 0 && height <= 23) { break; } else { printf("Wrong Input! Try Again.\n"); continue; } } while ((height < 0) || (height > 23));
这里有两个关键问题:
- 没检查
scanf的返回值:scanf("%d", &height)成功读取整数时会返回1,如果输入的不是整数,返回0(甚至EOF如果用户按了Ctrl+D/Ctrl+Z)。这时候height的值是未定义的(可能是垃圾值),你的范围判断完全没用,而且错误输入留在缓冲区里,导致scanf一直读垃圾,循环停不下来。 - 循环条件冗余:你在循环内部已经用
break跳出了,其实do-while的条件可以简化,但这不是核心问题,核心还是输入类型错误的处理。
修复后的代码
给你改好的代码,每一步都标了注释:
#include <stdio.h> int main(void) { int height; // 无限循环,直到输入正确才break do { printf("Welcome to Mario Pyramid Builder! Enter a number from 0 - 23: "); // 检查scanf是否成功读取了一个整数 int result = scanf("%d", &height); // 如果scanf失败(输入不是整数) if (result != 1) { printf("Wrong Input! Please enter an integer.\n"); // 清空输入缓冲区里的垃圾数据,直到读到换行符 while (getchar() != '\n'); continue; } // 检查范围是否合法 if (height >= 0 && height <= 23) { break; } else { printf("Wrong Input! Try Again.\n"); } } while (1); // 无限循环,靠内部break跳出 // 这里可以写生成金字塔的代码啦 printf("Building pyramid with height %d...\n", height); return 0; }
关键细节解释
- 检查
scanf返回值:通过result != 1判断是否读取失败,这是处理非整数输入的关键。 - 清空输入缓冲区:
while (getchar() != '\n');会把缓冲区里的所有字符(直到换行符)都读走,这样下次scanf就能读取新的输入,不会被之前的垃圾数据干扰。 - 简化循环条件:用
while(1)做无限循环,逻辑更清晰,只要输入正确就用break跳出。
这样修改后,不管用户输入字母、符号还是超出范围的数字,程序都能正确提示并重新要求输入啦!
内容的提问来源于stack exchange,提问作者UndeadAlien
相关产品推荐
相关产品推荐

