基础代码的循环结构和防呆设计--必须把用户当傻子才行?

在完成了最基础的选择后,循环结构是必然的,作为初学者,我必须说,简单的语法在使用中就可以把握,但逻辑的安排你必须绕过弯子,但其中的套路也有不少。
在循环语句的选择中,for语句绝对是十分好的选择,简洁明了,功能强大,我的第一个循环使用的就是for,不过我也才学会没多久,以下就是我的30人的工资计算:

include<stdio.h>

include<string.h>

int main()
{
float time1;
float time2;
int p;
char name[20];
char over[20];
char stop[20];
for(p=1;p<=30;p++){
printf("请输入姓名,时长,是否加班\n");
scanf("%s %f %s",name,&time1,over);
time1=time110;
if(strcmp(over,"是")==0){
printf("请输入加班时长\n");
scanf("%f",&time2);
time1=time2
12+time1;
}
printf("姓名:%s,工资:%.2f元\n",name,time1);
printf("是否停止记录\n");
scanf("%s",stop);
if(strcmp(stop,"是")==0)break;
}
return 0;
}
当时看书,觉得循环无非是在选择结构外面套,还是很简单的,后面又看到break,continue,这些可以对循环进程操作,觉得提前结束可能用得上,就加了个break,根本没想到防呆设计的核心就是循环和break,continue
我把这版发给AI,中途被break搞疯了,各种低级错误,甚至把输入放在循环外,这样用户根本没法再次输入,就滚雪球了
干完活,AI问我,用户输入工作时长时输入abc怎么办?
what?这和我有什么关系,AI告诉我,存在一个缓存区,往里面注水,读取时函数就按照顺序和相应的内容从里面读取,发现格式不对,就会返回一个零,然后保持上一个循环的对应数值,如果没有,就随机找一个垃圾值,也就是幽灵变量,继续执行程序,说什么这是信任,并且告诉我推荐把字符变量的输入格式控制好,否则数据溢出了
防呆设计,他为了维护系统不会因为乱输入搞崩溃,还要符合现实的工业逻辑
需要保证输入格式的正确
保证输入内容范围的合理
还要保证整个流程的实现
于是开始学习防呆设计,一开始,我打了一堆if嵌套,十分不美观,可读性较差,当我第二天看,我明白了可读性的作用,真的是眼花缭乱,然后我明白了,卫语句,只要单分支语句做筛选,不对就重来,再来个提示就行,在判断是否停止循环,这里我卡了好久,因为我的想法,你打错,就清理重来,太麻烦,就把卫语句放到一个小循环专门筛选,过了再继续判断是否停止循环,然后在其他地方,每次重启都要把清理缓存区
使用while(getchar()!='\n');我不知道这是什么,但是,可以用就行
我现在准备把我之前跟你讲过的那个工资系统,深入防呆设计,我还没弄呢

include<stdio.h>

include<string.h>

include<stdlib.h>

int main()
{
float time1;
float time2;
int p,ret1,ret2;
char name[20];
char over[20];
char stop[20];
time1=0;
time2=0;
for(p=1;p<=30;p++){
printf("请输入姓名,是否加班\n");
scanf("%19s %19s",name,over);
printf("请输入工作时长");
ret1=scanf("%f",&time1);
if(ret1!=1)
{
printf("输入错误,请重新输入数字");
while(getchar()!='\n');
continue;
}

if(time1>24||time1<=0)
{
printf("输入错误,请重新输入数字");
while(getchar()!='\n');
continue; //TODO
}
time1=time110;
if(strcmp(over,"是")==0)
{
printf("请输入加班时长\n");
ret2=scanf("%f",&time2);
if(ret2!=1)
{
printf("输入错误,请重新输入数字");
while(getchar()!='\n');
continue;
}
if(time2>6||time2<=0)
{
printf("输入错误,请重新输入数字");
while(getchar()!='\n');
continue; //TODO
}
time1=time2
12+time1;
}
printf("姓名:%s,工资:%.2f元\n",name,time1);
printf("是否停止记录\n");
while(1)
{
scanf("%s",stop);
if(strcmp(stop,"是")0)break;
if(strcmp(stop,"否")
0)break;
else {printf("输入错误,请重新输入,只能输入是或否");}
}
if(strcmp(stop,"是")==0)break;
}
return 0;
}怎么样?
真的是搞得我要崩溃了,这起码得搞6次以上,难怪程序员掉头发
不过我算是明白这个设计了,就是你要把每次输入都要严谨的面对,要把用户当做一个随时可能输入错东西的傻子,把格式的问题,输入的内容问题,还有循环的流程问题,都可以考虑清楚
格式不对就搞一个卫语句,告诉他,你这说的东西根本就不是一个东西,重新开始
内容不是我们需要的,就搞一个,就告诉用户,你你说的我们不需要的东西,重新开始
在结束不结束流程方面,你还得确定他输入的,还得搞一个小循环,确保它输入的只能是我们要求的两个可能之一,最后再重新判定他是否需要跳出循环
我的天爷
并且我注意到,现在这个还不是一个让人舒服的感觉,如果真正要舒服 你还得在每次输入判定前面加一个小循环,不然前面输入的全部归零,所以这里还要改
这才哪到哪,于是把每个卫语句都加小循环,又改了好几版,感觉被AI调教了。

include<stdio.h>

include<string.h>

int main()
{
float time1;
float time2;
int p,ret1,ret2;
char name[20];
char over[20];
char stop[20];
time1=0;
time2=0;
for(p=1;p<=30;p++){
printf("请输入姓名\n");
scanf("%19s",name);
while(1)
{
printf("请输入工作时长");
ret1=scanf("%f",&time1);
if(ret1!=1)
{
printf("输入错误,请重新输入数字");
while(getchar()!='\n');
continue;
}
if(time1>24||time1<=0)
{
printf("输入错误,请重新输入数字");
while(getchar()!='\n');
continue; //TODO
}
time1=time110;
break;
}
while(1)
{
printf("请输入是否加班\n");
scanf("%19s",over);
if(strcmp(over,"是")0)break;
if(strcmp(over,"否")
0)break;
else {printf("输入错误,请重新输入,只能输入是或否");while(getchar()!='\n');}
}
if(strcmp(over,"是")==0)
{
while(1)
{
printf("请输入加班时长\n");
ret2=scanf("%f",&time2);
if(ret2!=1)
{
printf("输入错误,请重新输入数字");
while(getchar()!='\n');
continue;
}
if(time2>6||time2<=0)
{
printf("输入错误,请重新输入数字");
while(getchar()!='\n');
continue; //TODO
}
break;
}
time1=time2
12+time1;
}

printf("姓名:%s,工资:%.2f元\n",name,time1);
while(1)
{
printf("是否停止记录\n");
scanf("%s",stop);
if(strcmp(stop,"是")0)break;
if(strcmp(stop,"否")
0)break;
else {printf("输入错误,请重新输入,只能输入是或否");while(getchar()!='\n');;}
}
if(strcmp(stop,"是")==0)break;
}
return 0;
}
我总结了一下。我错了这么多重点还是在于break和清空缓存区
这种局部重置一共有两种,一种呢是。输入课题的语句是文字啊之类的,这些是有对应选项的,你不能输入选项以外的,它就可以设置在不同选项,只要你输对了选项中的一个,你就可以直接退出,如果输错了就重新循环,所以其缓存区就可以在选错的那个分支里面,退出就在每一个符合的选项的分支后面
假种是数字相的,我们没法给他一个全部的准确的选项,但我们可以规定这个数字的范围和,退回那些不是数字的东西,这个逻辑的东西就是只要你输入不符合的东西,就直接退回,如果你输入符合的就继续在末尾退出循环,清空缓存区一般是在你被直接退回的那个分支里。
终于解决了!!!

posted @ 2026-10-21 15:33  叶忧无痕  阅读(3)  评论(0)    收藏  举报