C语言编程:程序运行总会在一个地方出错,如题

问题:
某班有5个学生,三门课。分别编写3个函数实现以下要求:
(1) 求各门课的平均分;
(2) 找出有两门以上不及格的学生,并输出其学号和不及格课程的成绩;
(3) 找出三门课平均成绩在85-90分的学生,并输出其学号和姓名。
主程序输入5个学生的成绩,然后调用上述函数输出结果。

代码已编写好,但问题在于,第一遍输入第一个同学的姓名和学号时正常,但输入第二个时便会出现 未输入名字之前,输入名字和输入学号一起出现,以至于无法输入第2-5个同学的姓名

截图如下
图片说明

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
float aver(int a,int b,int c);
int select(int a,int b,int c);
int bjg(int a,int b,int c);
 int main()
{
    struct book{
        char name[10];
        char number[10];
        int sub1;
        int sub2;
        int sub3;
    };
    struct book student[6];//为了初始化和顺序对应,故舍弃第一个结构数组元素不用 
    int i,j;
    for(i=1;i<6;i++)
    {
        printf("请输入第%d个同学的姓名:\n",i); 

        gets(student[i].name);
        printf("请输入第%d个同学的学号:\n",i);

        gets(student[i].number);

        printf("请输入第%d个同学的第1门课成绩:\n",i);
        scanf("%d",&student[i].sub1);
        printf("请输入第%d个同学的第2门课成绩:\n",i);
        scanf("%d",&student[i].sub2);
        printf("请输入第%d个同学的第3门课成绩:\n",i);
        scanf("%d",&student[i].sub3);
    }
    //输入部分结束
    float average[4];
    for(i=1;i<4;i++)
    {
        average[i]=aver(student[i].sub1,student[i].sub2,student[i].sub3);
        printf("第%d门课的平均成绩为:%f\n",i,average[i]);
    }
    //三门课平均分输出完毕

    for(i=1;i<4;i++)
    {
        if(bjg(student[i].sub1,student[i].sub2,student[i].sub3)>=2)
        {
            printf("不及格超过2门\n"); 
            puts(student[i].name);
            puts(student[i].number);
            if(student[i].sub1<60)
             printf("%d ",student[i].sub1);
            if(student[i].sub2<60)
             printf("%d ",student[i].sub2);
            if(student[i].sub3<60)
             printf("%d ",student[i].sub3);
        }

    }
    for(i=1;i<4;i++)
    {
        if(select(student[i].sub1,student[i].sub2,student[i].sub3)==1)
        {
            printf("成绩在85-90之间:\n");
            puts(student[i].name);
            puts(student[i].number);
        }
    }

} 
 //函数1:求平均分数 
float aver(int a,int b,int c)
{
    return((a+b+c)/3);
}
//函数2:求不及格门数超过2的同学 
int bjg(int a,int b,int c)
{
    int count=0;
    if(a<60)
     count+=1;
    if(b<60)
     count+=1;
    if(c<60)
     count+=1;
    if(count>2)
     return count;
    else return 0;
}
//函数3:求三门课平均成绩在85-90分的学生 
int select(int a,int b,int c)
{
    if(((a+b+c)/3)>=85&&((a+b+c)/3)<=90)
     return 1;
    else 
     return 0;
}

3个回答

在for循环开头加上fflush(stdin);即可

除此之外,你的代码还有2个隐藏的问题,就是char number[10];如果你的学号是10位,那么这个长度不够,字符串结束需要一个\0,所以应该定义11或者更长的数组。
return((a+b+c)/3);整数/整数,这个是整除,如果你要提高精度,应该写 /3.0f

完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
float aver(int a,int b,int c);
int select(int a,int b,int c);
int bjg(int a,int b,int c);
 int main()
{
    struct book{
        char name[10];
        char number[11];
        int sub1;
        int sub2;
        int sub3;
    };
    struct book student[6];//为了初始化和顺序对应,故舍弃第一个结构数组元素不用 
    int i,j;
    for(i=1;i<6;i++)
    {
        fflush(stdin);
        printf("请输入第%d个同学的姓名:\n",i); 

        gets(student[i].name);
        printf("请输入第%d个同学的学号:\n",i);

        gets(student[i].number);

        printf("请输入第%d个同学的第1门课成绩:\n",i);
        scanf("%d",&student[i].sub1);
        printf("请输入第%d个同学的第2门课成绩:\n",i);
        scanf("%d",&student[i].sub2);
        printf("请输入第%d个同学的第3门课成绩:\n",i);
        scanf("%d",&student[i].sub3);
    }
    //输入部分结束
    float average[4];
    for(i=1;i<4;i++)
    {
        average[i]=aver(student[i].sub1,student[i].sub2,student[i].sub3);
        printf("第%d门课的平均成绩为:%f\n",i,average[i]);
    }
    //三门课平均分输出完毕

    for(i=1;i<4;i++)
    {
        if(bjg(student[i].sub1,student[i].sub2,student[i].sub3)>=2)
        {
            printf("不及格超过2门\n"); 
            puts(student[i].name);
            puts(student[i].number);
            if(student[i].sub1<60)
             printf("%d ",student[i].sub1);
            if(student[i].sub2<60)
             printf("%d ",student[i].sub2);
            if(student[i].sub3<60)
             printf("%d ",student[i].sub3);
        }

    }
    for(i=1;i<4;i++)
    {
        if(select(student[i].sub1,student[i].sub2,student[i].sub3)==1)
        {
            printf("成绩在85-90之间:\n");
            puts(student[i].name);
            puts(student[i].number);
        }
    }

} 
 //函数1:求平均分数 
float aver(int a,int b,int c)
{
    return((a+b+c)/3.0f);
}
//函数2:求不及格门数超过2的同学 
int bjg(int a,int b,int c)
{
    int count=0;
    if(a<60)
     count+=1;
    if(b<60)
     count+=1;
    if(c<60)
     count+=1;
    if(count>2)
     return count;
    else return 0;
}
//函数3:求三门课平均成绩在85-90分的学生 
int select(int a,int b,int c)
{
    //if(((a+b+c)/3.0f)>=85&&((a+b+c)/3.0f)<=90) 这里既然你有aver了,可以直接调用
    if(aver(a,b,c)>=85&& aver(a,b,c)<=90)
     return 1;
    else 
     return 0;
}

运行结果:
图片说明

如果问题得到解决,请点回答右边的采纳,谢谢

qq_18404993
Zijeak 十分感谢大佬,讲得很详细,受教了
接近 2 年之前 回复

这个是输入函数的问题,你必须重新用一个输入函数吃掉你的回车,这是C语言的一个BUG,我们老师也讲过。

qq_18404993
Zijeak 感谢大佬指点
接近 2 年之前 回复

你在输入第一个学生的最后一门成绩之后按了一下回车,这个回车没被scanf接收,而gets就是读取一行字符,就把刚刚回车时的空行读取了,所以用getchar()在输入最后一门成绩之后,回收这个回车键

 for (i = 1; i<6; i++)
    {
        printf("请输入第%d个同学的姓名:\n", i);
        gets_s(student[i].name);
        printf("请输入第%d个同学的学号:\n", i);
        gets_s(student[i].number);
        printf("请输入第%d个同学的第1门课成绩:\n", i);
        scanf("%d", &student[i].sub1);
        printf("请输入第%d个同学的第2门课成绩:\n", i);
        scanf("%d", &student[i].sub2);
        printf("请输入第%d个同学的第3门课成绩:\n", i);
        scanf("%d", &student[i].sub3);
        getchar();
    }
qq_18404993
Zijeak 感谢大佬指点,指出问题关键所在
接近 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐