“利用scanf函数从键盘接收一字符(或整数)时,它只读入字符(或整数)本身,而把字符(或整数)后的回车符留在输入缓冲区内;gets函数从标准的输入读取,如果使用gets函数给字符数组输入字符串时,字符数组不能指定长度,因为,只要字符数组的长度小于gets函数读取的行缓存的大小,即使你输入的字符数大于你所规定的字符数组的长度,gets函数也会接收所输入的全部字符,造成字符数组越界。因此,gets是一个不推荐使用的函数。一般对于初学者来说,容易把scanf和gets函数混用,出现一些问题,有下面两种情况:
1、gets在scanf前调用,这种调用一般不会出现什么问题,可以正常输入。
2、scanf在gets前调用,这种情况就会出现问题,当输入完scanf中的变量时,运行到gets函数,则不让输入任何字符,出现此问题的原因是gets函数接收了scanf输入完后的回车符,解决的办法是在scanf和gets中间,用getchar函数接收掉回车符,这样就不会出现任何问题了。但是这个只能解决有一个换行符的问题。
要想解决多个的问题,可以在scanf之后使用下面的代码来做:
if(getchar()!='\n') { continue; }
不过说真的建议别使用gets,不是很安全,而且只适用于玩具程序。”
谢谢https://bbs.csdn.net/topics/这篇文章讨论中https://me.csdn.net/wayne_hust的解答。
这个gets()函数我真的哔了狗了!整整花了一个小时,才把一个简单的结构体的程序搞清楚!
题干:输出3门课平均成绩、总成绩最高的学生的信息:
代码:
#include<stdio.h> #define N 2 struct student{ int num; char name[20]; double c1,c2,c3; double total; double average; }; int main(){ struct student stu[N]; int i,maxi; double max; for(i=0;i<N;i++){ scanf("%d",&stu[i].num); gets(stu[i].name); scanf("%lf%lf%lf",&stu[i].c1,&stu[i].c2,&stu[i].c3); stu[i].total=stu[i].c1+stu[i].c2+stu[i].c3; stu[i].average=stu[i].total/3; } maxi=0; max=stu[0].total; for(i=1;i<N;i++){ if(max<stu[i].total){ max=stu[i].total; maxi=i; } } for(i=0;i<N;i++){ printf("学号:%d\n",stu[i].num); printf("姓名:%s\n",stu[i].name); printf("三门课程成绩c1:%lf,c2:%lf,c3:%lf\n",stu[i].c1,stu[i].c2,stu[i].c3); printf("总分:%lf\n",stu[i].total); printf("平均分:%lf\n",stu[i].average); } return 0; }
测试的时候:输入数据的时两层循环,可是当从键盘上读入数据的时候,刚循环完一层就结束了!(。。)
之前想到输入字符按回车的时候可能会读入换行符,然后就上网找了一下他人的帮助。确实就是因为读到了回车符导致整个过程输入数据的时候没有正确的输入。
解决方法:按照上面老铁的解决方法,知道了问题所在,添加了一小段代码:
然后程序就能正常运行了:
scanf("%d",&stu[i].num); if(getchar()!='\n'){ continue; } gets(stu[i].name); scanf("%lf%lf%lf",&stu[i].c1,&stu[i].c2,&stu[i].c3);
关于我对这段代码的理解:首先getchar()是一个函数,当它出现在程序中的某一行时,它就会被执行(即不管if()里面的判断为真为假,getchar()都会执行一次,真假影响的只是continue执行与否)。那么在认识到这个要点之后,我们来分析这段代码。上一行的scanf()函数,我们在键盘上输入123再按回车的时候,此时,回车符将会读取到缓冲区中,然后执行了getchar()函数,回车符正是\n,且它已经被getchar()函数接收了,然后就不执行if()内的continue。那么,缓冲区中的回车符已经不复存在,那我们再执行gets()函数的时候,gets()接收的就是纯粹的键盘上读取的字符而不包括缓冲区中的回车符(实际上这个回车符被getchar()接收了)。那么我们就能正常的读取到我们设想到的数据而不发生错误!
当然了,我们还可以在scanf()和gets()之间使用fflush(stdin);重新清空缓冲区,这样gets()也不会读取到回车符导致不能正确读取数据。
scanf("%d",&stu[i].num); fflush(stdin); gets(stu[i].name); scanf("%lf%lf%lf",&stu[i].c1,&stu[i].c2,&stu[i].c3);
亲测可行!
今天的文章
c++基础语法_c++基础语法分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/61461.html