C语言笔记-学生成绩管理

前言

这篇文章和代码是专门针对下方学生成绩管理这个题目,使用的语言为C
全部的代码为小狐狸独立完成,不存在抄袭的情况,如有雷同纯属巧合。
本代码可能含有BUG,若出现BUG的话可以联系小狐狸
文章末尾有附带题目+代码下载链接,有需要朋友可自行下载。

题目信息

有N名学生,每名学生含有如下信息:学号、姓名、某四门课的成绩,并计算其总分,用一结构体数组表示之。然后实现以下功能:
(1)将这些数据存放至文件stuf.dat中;
(2)将文件中的数据读出至结构体数组中,并显示之;
(3)输出总分最高分和最低分的名字;
(4)输出总分在340分,单科成绩不低于80分的名单;
(5)求出各科平均分数;
(6)按总分排名;
(7)输出补考名单并存入文件。

生成测试数据-C语言

因为每次输入学生数据的时候很费力,得一直打,还容易打错,所以就弄了一个可随机的学生数据。
生成测试数据的代码生成的学生数据仅在本题目中使用,使用到了随机数生成的知识。

C语言笔记-指定范围下随机数的生成
1.1
1.2
在这里插入图片描述

/*
代码作者:小狐狸
联系QQ:1307509553
使用语言: c
原贴链接: https://blog.csdn.net/smallfox233/article/details/105086499
代码介绍:
生成的学生数据student.txt仅在学生信息管理系统中使用,
你可以在生成学生数据后打开student.txt文件直接复制黏贴即可.

生成stuf.dat文件与student.txt文件的内容相同,
stuf.dat可移动到学生信息管理主程序.c的目录下使用.


生成从a~(a+b-1)的随机数赋值给Y:
1. srand((int)time(NULL))
2. Y=rand()%b+a;
*/
#include<stdio.h>
#include<stdlib.h>  //随机数、清屏使用需要的文件头
#include<time.h>    //随机数需要的文件头
#define OK 1
#define ERROR -1
#define Max 99
int CreateTest(int N,int Len)//创建测试学生数据,并存入student.txt和stuf.dat文件,N为学生个数,Len为学生学号长
{
    char Name[Max]={'f','o','x'};//若需要变更学生姓名在此处变更即可
    FILE *op,*op2;//文件指针
    op=fopen("student.txt","w");//以重建模式打开文件
    op2=fopen("stuf.dat","w");//以重建模式打开文件
    int i,j;
    srand((int)time(NULL));//设置随机数种子
    fprintf(op,"%d\n",N);//第一行为文件中学生的总数
    fprintf(op2,"%d\n",N);//第一行为文件中学生的总数
    for(i=1;i<=N;i++)//学生总测试数
    {
        for(j=1;j<=Len;j++)//学号
        {
            int fox;//临时变量
            if(j==1)//首位不为0,从1-9选择
            {
                fox=rand()%9+1;//生成从1-9的随机数
                fprintf(op,"%d",fox);//存入student.txt
                fprintf(op2,"%d",fox);//存入stuf.dat
            }
            else//从0-9选择
            {
                fox=rand()%9;//生成从0-9的随机数
                fprintf(op,"%d",fox);//存入student.txt
                fprintf(op2,"%d",fox);//存入stuf.dat
            }
        }
        fprintf(op," ");
        fprintf(op2," ");
        int score1,score2,score3,score4;
        score1=rand()%100+1;//生成从1-100的随机数
        score2=rand()%100+1;
        score3=rand()%100+1;
        score4=rand()%100+1;
        //student.txt文件操作
        fprintf(op,"%s%d ",Name,i);//姓名
        fprintf(op,"%d ",score1);//成绩1
        fprintf(op,"%d ",score2);//成绩2
        fprintf(op,"%d ",score3);//成绩3
        fprintf(op,"%d\n",score4);//成绩4
        //stuf.dat文件操作
        fprintf(op2,"%s%d ",Name,i);//姓名
        fprintf(op2,"%d ",score1);//成绩1
        fprintf(op2,"%d ",score2);//成绩2
        fprintf(op2,"%d ",score3);//成绩3
        fprintf(op2,"%d\n",score4);//成绩4
    }
    fclose(op);
    return OK;
}
int main()
{

    while(1)
    {
        int fox;//临时变量
        printf("---------------<学生随机数据生成系统>-----------------\n");
        printf("|       0. 退出系统                                  |\n");
        printf("|       1. 生成新的数据存入student.txt和stuf.dat文件 |\n");
        printf("|       2. 清屏                                      |\n");
        printf("------------------------------------------------------\n");
        scanf("%d",&fox);
        if(fox==0) break;
        else if(fox==1)
        {
            int N;//学生总数
            int Len;//学号长度
            printf("测试学生总数: ");
            scanf("%d",&N);
            printf("学生学号长度: ");
            scanf("%d",&Len);
            CreateTest(N,Len);
            printf("创建成功,请到student.txt中查看!\n");
        }
        else system("cls");
    }
    return OK;
}

学生成绩管理-C语言

代码所必须的注释都已经写在代码开头和代码中,删除注释代码前请先浏览一遍注释。
考虑到课设老师可能会要求多写一些功能,所以就添加了一个功能11,用于查找各科不及格学生

[1]. 除了文件导入功能的效果展示

2.1

[2]. 文件导入功能展示

在这里插入图片描述

[3]. 代码

/*
代码作者:小狐狸
联系QQ:1307509553
使用语言: c
原贴链接: https://blog.csdn.net/smallfox233/article/details/105086499
代码介绍:
若作为作业进行提交的话,建议对某些变量名进行变更.
此代码仅为了实现题目要求的功能,需要拓展的话可自己设计新的函数.
对菜单函树Menu()进行提示修改,并添加到main()主函数的switch()语句中即可.

各个函数是按菜单中数字顺序进行放置,可根据主菜单中所需功能查找对应函数位置
代码开头的注释可自行删除.
经过测试若学号或姓名达到8位或8位以上的字符时,数据将会不对齐

若使用%s进行输入字符串时,取址符'&'可进行省略,
strcpy(字符串A,字符串B),将字符串B复制给字符串A.
文件当中仅保存学生总数、学号、姓名、成绩1、成绩2、成绩3、成绩4

排序部分使用的是冒泡排序,若想要运算的效率更高的话,
可以采用基数排序、归并排序、快速排序、堆排序、简单选择排序、希尔排序、直接插入排序算法.

Windows系统下OS命令行中清屏: cls
c语言中清屏: system('cls');

文件操作全流程:
1. FILE *文件指针=fopen("文件路径","操作方式")
常用操作方式有以下三种。
w: 为重新创建文件并写入
r: 为只读取文件,不对文件内容进行修改,要求文件必须存在否则返回NULL
a: 为追加内容到文件末尾
+: 可读可写,和w、r、a进行组合而不能单独存在,即w+、a+、r+

2.
将变量内容存入: fprintf(文件指针,"%s",变量);  //%s表示字符串型变量
读取内容到变量: fscanf(文件指针,"%s",变量);
每次的存入和读取类似于排队,前者被存入或读取后,
下一次的存入或读取将会跳过已操作的那些,
文件中以空白符为两个不同内容的分隔,
空格、换行、制表符(tab)都算是空白符
如: tu r中tu和r被空格隔开,tu若被fscanf()取出一次后,
    下一次的fscanf()读取的是r,fprintf()与fscanf()类似

3. 关闭文件: fclose(文件指针);
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define OK 1
#define ERROR -1
#define Max 99
struct
{
    char Number[Max];//学号
    char Name[Max];//姓名
    int Score1;//成绩1
    int Score2;//成绩2
    int Score3;//成绩3
    int Score4;//成绩4
    int All;//四科成绩总分
    int Avg;//平均分
}STU[Max],FOX[Max],NEW[Max];//学生结构体数组,下标从1开始
//STU用于存储学生数据,FOX、NEW为临时使用的结构体数组
int Menu();//菜单显示
int InputStudent(int N);//输入学生信息,N为学生总数
int PrintStudent(int N);//显示学生信息,N为学生总数
int Upload(int N);//将结构体数组中的数据存入文件,N为学生总数
int AddUpload(int N);//将学生信息存入文件末尾,N为学生总数
int Download();//将文件数据读出至结构体数组,返回值为学生总数
int HighLowName(int N);//输出最高分和最低分的名字,N为学生总数
int PrintSix(int N);//输出总分在340分,单科成绩不低于80分的名单
int PrintAverage(int N);//计算所有学生的平均分并显示
int PrintLevel(int N);//按总分进行排名并打印,N为学生总数
//未使用的函数:int PrintLevel2(int N);//按总分进行排名并打印,N为学生总数
int UploadFail(char loser[],char course[]);//将需要补考的名单存入文件fail.txt,loser存储不及格学生的姓名,course为该学生不及格的科目.
int Fail(int N);//将需要补考的名单进行打印
int ScoreFail(int N);//打印指定科目不及格的学生
int main()
{
    int N=0;//学生总数,N不能放于while循环中,否则进行一次循环后.N值将会改变
    while(1)
    {
        int fox;//临时变量
        Menu();//主菜单显示
        printf("请选择: ");
        scanf("%d",&fox);
        if(fox==0) break;//退出操作
        switch(fox)
        {
            case 1://输入学生信息
                {
                    while(1)//确保N值≥0,当N=0时将不会执行输入学生信息
                    {
                        printf("学生总数(退出请输入0): ");
                        scanf("%d",&N);
                        if(N<0)//N为负值时
                            printf("请输入≥0的数!");
                        else break;
                    }
                    InputStudent(N);
                }
                break;
            case 2://显示学生信息
                {
                    if(N==0)//没有学生信息时
                    {
                        printf("请先输入学生信息!\n");
                        break;
                    }
                    else   PrintStudent(N);
                }
                break;
            case 3://将学生数据存入stuf.dat,若已存在则添加至末尾
                {
                    FILE *Fox;//临时文件指针
                    if((Fox=fopen("stuf.dat","r"))!=NULL)//若文件存在时
                    {
                        AddUpload(N);//将数据添加到文件末尾
                    }
                    else//若文件不存在时直接存入
                        Upload(N);
                }
                break;
            case 4://将文件数据读出至结构体
                {
                    FILE *Fox;//临时文件指针
                    if((Fox=fopen("stuf.dat","r"))==NULL)//若文件不存在时
                    {
                        printf("stuf.dat文件不存在,请先创建一个再执行此操作!\n");
                    }
                    else//文件存在时
                    {
                        N=Download();//返回一个文件中的学生总数
                        if(N==0)//当文件中的学生人数为0时
                            printf("stuf.dat文件中没有学生信息!\n");
                    }
                }
                break;
            case 5://输出总分最高分和总分最低分的名字
                {
                    HighLowName(N);
                }
                break;
            case 6://输出总分在340分,单科成绩不低于80分的名单
                {
                    PrintSix(N);
                }
                break;
            case 7://求出每个学生的各科平均数并显示
                {
                    PrintAverage(N);
                }
                break;
            case 8://按总分排名并打印
                {
                    PrintLevel(N);//使用NEW数组来排序和打印
                }
                break;
            case 9://输出补考名单并存入文件fail.txt
                {
                    Fail(N);
                }
                break;
            case 10://打印指定科目不及格的学生
                {
                    ScoreFail(N);
                }
                break;
            case 11://清屏
                {
                    system("cls");//需要使用头文件#include<stdlib.h>才不会报错
                }
                break;
            default: break;
        }
    }
    printf("退出成功!\n");
    return 0;
}
int Menu()//菜单显示
{
    printf("---------------------------------------------------------------\n");
    printf("|       0. 退出系统                                           |\n");
    printf("|       1. 输入学生信息                                       |\n");
    printf("|       2. 显示学生信息                                       |\n");
    printf("|       3. 将学生数据存入stuf.dat,若已有数据则添加至末尾      |\n");
    printf("|       4. 将文件数据导出至结构体数组                         |\n");
    printf("|       5. 输出总分最高分和最低分的名字                       |\n");
    printf("|       6. 输出总分在340分,单科成绩不低于80分的名单           |\n");
    printf("|       7. 求出各科平均分数并打印                             |\n");
    printf("|       8. 按总分排名并打印                                   |\n");
    printf("|       9. 输出补考名单并存入文件fail.txt                     |\n");
    printf("|       10.打印指定科目不及格的学生名单                       |\n");
    printf("|       11. 清屏                                              |\n");
    printf("---------------------------------------------------------------\n");
    return OK;
}
int InputStudent(int N)//输入学生信息,N为学生总数
{
    int i;
    if(N<=0)
        return ERROR;
    printf("请按学号 姓名 成绩1 成绩2 成绩3 成绩4填写!\n");
    for(i=1;i<=N;i++)//将所有学生数据存入结构体数组
    {
        printf("第%d名学生:\n",i);
        scanf("%s",STU[i].Number);//学号
        scanf("%s",STU[i].Name);//姓名
        scanf("%d",&STU[i].Score1);//成绩1
        scanf("%d",&STU[i].Score2);//成绩2
        scanf("%d",&STU[i].Score3);//成绩3
        scanf("%d",&STU[i].Score4);//成绩4
        STU[i].All=STU[i].Score1+STU[i].Score2+STU[i].Score3+STU[i].Score4;//计算总分
    }
    return OK;
}
int PrintStudent(int N)//显示学生信息,N为学生总数
{
    int i;
    if(N<=0)
        return ERROR;
    printf("=============================================<分隔线>=======================================================\n");
    printf("学号\t\t姓名\t\t成绩1\t\t成绩2\t\t成绩3\t\t成绩4\t\t总分\n");
    for(i=1;i<=N;i++)
    {
        printf("%s\t\t",STU[i].Number);//学号
        printf("%s\t\t",STU[i].Name);//姓名
        printf("%d\t\t",STU[i].Score1);//成绩1
        printf("%d\t\t",STU[i].Score2);//成绩2
        printf("%d\t\t",STU[i].Score3);//成绩3
        printf("%d\t\t",STU[i].Score4);//成绩4
        STU[i].All=STU[i].Score1+STU[i].Score2+STU[i].Score3+STU[i].Score4;//计算总分
        printf("%d\n",STU[i].All);//总分
    }
    printf("=============================================<分隔线>=======================================================\n");
    printf("显示成功!\n");
    return OK;
}
int Upload(int N)//将结构体数组中的数据存入文件,N为学生总数
{
    FILE *op;//文件指针,
    if((op=fopen("stuf.dat","w"))==NULL)//文件指针创建失败时
        return ERROR;
    int i;
    fprintf(op,"%d\n",N);//将学生人数存入文件第一行
    for(i=1;i<=N;i++)//将学生信息存入文件
    {
        fprintf(op,"%s ",STU[i].Number);//学号
        fprintf(op,"%s ",STU[i].Name);//姓名
        fprintf(op,"%d ",STU[i].Score1);//第一门成绩
        fprintf(op,"%d ",STU[i].Score2);//第二门成绩
        fprintf(op,"%d ",STU[i].Score3);//第三门成绩
        fprintf(op,"%d ",STU[i].Score4);//第四门成绩
    }
    fclose(op);
    return OK;
}
int AddUpload(int N)//将学生信息存入文件末尾,N为学生总数
{//使用此函数前需保证stuf.dat已存在
    if(N<=0)
        return ERROR;
    FILE *op;//文件指针
    int i,j;
    int n;//文件当中的学生数
    op=fopen("stuf.dat","r");//只读形式
    fscanf(op,"%d",&n);//由于需要变更文件首行的学生总数,所以需要重建文件
    for(i=1;i<=n;i++)//将文件内容先暂存FOX数组
    {
        fscanf(op,"%s",FOX[i].Number);//学号
        fscanf(op,"%s",FOX[i].Name);//姓名
        fscanf(op,"%d",&FOX[i].Score1);//成绩1
        fscanf(op,"%d",&FOX[i].Score2);//成绩2
        fscanf(op,"%d",&FOX[i].Score3);//成绩3
        fscanf(op,"%d",&FOX[i].Score4);//成绩4
    }
    fclose(op);
    for(i=N+1,j=2;i<=N+n;j++,i++)//将STU数据添加到FOX数据中
    {
        strcpy(FOX[i].Number,STU[j].Number);//学号
        strcpy(FOX[i].Name,STU[j].Name);//姓名
        FOX[i].Score1=STU[j].Score1;//成绩1
        FOX[i].Score2=STU[j].Score2;//成绩2
        FOX[i].Score3=STU[j].Score3;//成绩3
        FOX[i].Score4=STU[j].Score4;//成绩4
        FOX[i].All=STU[j].All;//总分
    }
    N+=n;//添加学生总数
    op=fopen("stuf.dat","w");//重建形式
    fprintf(op,"%d\n",N);
    for(i=1;i<=N;i++)//将学生信息存入文件
    {
        fprintf(op,"%s ",FOX[i].Number);//学号
        fprintf(op,"%s ",FOX[i].Name);//姓名
        fprintf(op,"%d ",FOX[i].Score1);//成绩1
        fprintf(op,"%d ",FOX[i].Score2);//成绩2
        fprintf(op,"%d ",FOX[i].Score3);//成绩3
        fprintf(op,"%d ",FOX[i].Score4);//成绩4
    }
    fclose(op);
    return OK;
}
int Download()//将文件数据读出至结构体数组,返回值为学生总数
{//因为需要返回N的值,所以使用此函数前.需要先验证文件stuf.dat是否存在
    FILE *op;
    int N=0;
    int i;
    op=fopen("stuf.dat","r");
    fscanf(op,"%d",&N);//读取文件第一行的学生总数
    for(i=1;i<=N;i++)
    {
        fscanf(op,"%s",STU[i].Number);//读取学号
        fscanf(op,"%s",STU[i].Name);//读取姓名
        fscanf(op,"%d",&STU[i].Score1);//读取成绩1
        fscanf(op,"%d",&STU[i].Score2);//读取成绩2
        fscanf(op,"%d",&STU[i].Score3);//读取成绩3
        fscanf(op,"%d",&STU[i].Score4);//读取成绩4
    }
    fclose(op);
    return N;//返回学生总数
}
int HighLowName(int N)//输出最高分和最低分的名字,N为学生总数
{
    if(N<0)
        return ERROR;
    int high;//标记总分最高学生的下标
    int low;//标记总分最低学生的下标
    int i;
    int fox=STU[1].All;//临时变量
    for(i=1;i<=N;i++)//查找总分最高学生的下标
    {
        if(fox<STU[i].All)
        {
            fox=STU[i].All;
            high=i;
        }
    }
    for(i=1;i<=N;i++)//查找总分最低学生的下标
    {
        if(fox>STU[i].All)
        {
            fox=STU[i].All;
            low=i;
        }
    }
    printf("总分最高的学生: %s\n",STU[high].Name);
    printf("总分最低的学生: %s\n",STU[low].Name);
    return OK;
}
int PrintSix(int N)//输出总分在340分,单科成绩不低于80分的名单
{
    if(N<=0)
        return ERROR;
    int i;
    int sum=0;
    int flag=0;//若学生中有符合条件的,flag为1
    printf("总分在340分,且成绩不低于80分的学生如下:\n");
    for(i=1;i<=N;i++)//在STU结构体数组中循环遍历符合条件的学生
    {
        if(STU[i].All==340&&STU[i].Score1>=80&&STU[i].Score2>=80&&STU[i].Score3>=80&&STU[i].Score4>=80)//符合条件时
        {
            printf("%d. %s ",i,STU[i].Name);
            sum++;
            flag=1;
        }
        if(sum%5==0&&flag==1)//每五个学生姓名为一行,当没有符合条件的学生时不需要换行
            printf("\n");
    }
    if(flag==0)
        printf("无符合条件的学生!\n");
    return OK;
}
int PrintAverage(int N)//计算所有学生的平均分并显示
{
    if(N<=0)
        return ERROR;
    int i;
    printf("学生\t\t\t平均分\n");
    for(i=1;i<=N;i++)//总分虽然在输入时已算好了,但是如果是从文件中导入的话就没有总分信息
    {
        STU[i].Avg=(STU[i].Score1+STU[i].Score2+STU[i].Score3+STU[i].Score4)/4;//计算平均分
        printf("%s\t\t\t%d\n",STU[i].Name,STU[i].Avg);//打印平均分
    }
    return OK;
}
int PrintLevel(int N)//按总分进行排名并打印,N为学生总数
{
    //此函数与PrintLevel2的功能一样,但不会打乱原有STU的顺序
    if(N<=0)
        return ERROR;
    int i,j;
    for(i=1;i<=N;i++)//将STU的数据存入NEW
    {
        strcpy(NEW[i].Number,STU[i].Number);//学号
        strcpy(NEW[i].Name,STU[i].Name);//姓名
        NEW[i].Score1=STU[i].Score1;//成绩1
        NEW[i].Score2=STU[i].Score2;//成绩2
        NEW[i].Score3=STU[i].Score3;//成绩3
        NEW[i].Score4=STU[i].Score4;//成绩4
        STU[i].All=STU[i].Score1+STU[i].Score2+STU[i].Score3+STU[i].Score4;//计算总分
        NEW[i].All=STU[i].All;//总分
    }
    for(i=1;i<=N;i++)//使用冒泡排序法对NEW进行递增排序
    {
        for(j=1;j<N;j++)//到达最后一个学生时,不进行判断
        {
            if(NEW[j].All>NEW[j+1].All)////若当前学生总分比后者还大则后移
            {//将学生信息互换
                char number[Max];//学号
                char name[Max];//姓名
                int score1;//成绩1
                int score2;//成绩2
                int score3;//成绩3
                int score4;//成绩4
                int all;//总分
                int avg;//平均分
                /*学号互换*/
                strcpy(number,NEW[j].Number);
                strcpy(NEW[j].Number,NEW[j+1].Number);
                strcpy(NEW[j+1].Number,number);
                /*姓名互换*/
                strcpy(name,NEW[j].Name);
                strcpy(NEW[j].Name,NEW[j+1].Name);
                strcpy(NEW[j+1].Name,name);
                /*成绩1互换*/
                score1=NEW[j].Score1;
                NEW[j].Score1=NEW[j+1].Score1;
                NEW[j+1].Score1=score1;
                /*成绩2互换*/
                score2=NEW[j].Score2;
                NEW[j].Score2=NEW[j+1].Score2;
                NEW[j+1].Score2=score2;
                /*成绩3互换*/
                score3=NEW[j].Score3;
                NEW[j].Score3=NEW[j+1].Score3;
                NEW[j+1].Score3=score3;
                /*成绩4互换*/
                score4=NEW[j].Score4;
                NEW[j].Score4=NEW[j+1].Score4;
                NEW[j+1].Score4=score4;
                /*总分互换*/
                all=NEW[j].All;
                NEW[j].All=NEW[j+1].All;
                NEW[j+1].All=all;
            }
        }
    }
    printf("=============================================<分隔线>=======================================================\n");
    printf("学号\t\t姓名\t\t成绩1\t\t成绩2\t\t成绩3\t\t成绩4\t\t总分\n");
    for(i=1;i<=N;i++)//PrintStudent函数只显示STU结构体数组的信息,而此处需要打印的是NEW的信息,不能直接调用函数PrintStudent
    {
        printf("%s\t\t",NEW[i].Number);//学号
        printf("%s\t\t",NEW[i].Name);//姓名
        printf("%d\t\t",NEW[i].Score1);//成绩1
        printf("%d\t\t",NEW[i].Score2);//成绩2
        printf("%d\t\t",NEW[i].Score3);//成绩3
        printf("%d\t\t",NEW[i].Score4);//成绩4
        NEW[i].All=NEW[i].Score1+NEW[i].Score2+NEW[i].Score3+NEW[i].Score4;//计算总分
        printf("%d\n",NEW[i].All);//总分
    }
    printf("=============================================<分隔线>=======================================================\n");
    return OK;
}

int PrintLevel2(int N)//按总分进行排名并打印,N为学生总数
{
    //此函数与PrintLevel的功能相同,只不过没有使用到NEW数组
    //此函数将会打乱原有的STU数组的顺序为递增,直接显示可以直接调用PrintStudent函数
    int i,j;
    for(i=1;i<=N;i++)//对STU数组进行递增排序
    {
        for(j=1;j<N;j++)//j=N时不需要后移
        {
            STU[j].All=STU[j].Score1+STU[j].Score2+STU[j].Score3+STU[j].Score4;//计算总分
            STU[j+1].All=STU[j+1].Score1+STU[j+1].Score2+STU[j+1].Score3+STU[j+1].Score4;//计算总分
            if(STU[j].All>STU[j+1].All)//若第j个学生总分较大则后移
            {
                char number[Max];//学号
                char name[Max];//姓名
                int score1;//成绩1
                int score2;//成绩2
                int score3;//成绩3
                int score4;//成绩4
                int all;//总分
                int avg;//平均分
                /*学号互换*/
                strcpy(number,STU[j].Number);
                strcpy(STU[j].Number,STU[j+1].Number);
                strcpy(STU[j+1].Number,number);
                /*姓名互换*/
                strcpy(name,STU[j].Name);
                strcpy(STU[j].Name,STU[j+1].Name);
                strcpy(STU[j+1].Name,name);
                /*成绩1互换*/
                score1=STU[j].Score1;
                STU[j].Score1=STU[j+1].Score1;
                STU[j+1].Score1=score1;
                /*成绩2互换*/
                score2=STU[j].Score2;
                STU[j].Score2=STU[j+1].Score2;
                STU[j+1].Score2=score2;
                /*成绩3互换*/
                score3=STU[j].Score3;
                STU[j].Score3=STU[j+1].Score3;
                STU[j+1].Score3=score3;
                /*成绩4互换*/
                score4=STU[j].Score4;
                STU[j].Score4=STU[j+1].Score4;
                STU[j+1].Score4=score4;
                /*总分互换*/
                all=STU[j].All;
                STU[j].All=STU[j+1].All;
                STU[j+1].All=all;
            }
        }
    }
    PrintStudent(N);//对STU数组直接打印
    return OK;
}
int UploadFail(char loser[],char course[])//将需要补考的名单存入文件fail.txt,loser存储不及格学生的姓名,course为该学生不及格的科目.
{
    //failt.txt文件中不含学生总数,需要建立读取fail.txt函数的话,可以在传入文件的末尾中添加一个特殊字符来判断是否读取完文件
    FILE *read,*op;
    if((read=fopen("file.txt","r"))==NULL)//若fail.txt文件不存在时已重建形式打开文件
        op=fopen("file.txt","w");
    else op=fopen("file.txt","a+");//否则以追加形式打开文件
    fprintf(op,"%s %s\n",loser,course);//文件中每行为一个学生补考信息,补考姓名+补考科目
    fclose(read);
    fclose(op);
    return OK;
}
int Fail(int N)//将需要补考的名单进行打印
{
    if(N<=0)
        return ERROR;
    int i;
    printf("\n==============<分割线>====================\n");
    printf("不及格学生\t不可格课程\n");
    for(i=1;i<=N;i++)
    {
        if(STU[i].Score1<60)//学科1不及格时
        {
            UploadFail(STU[i].Name,"科目1");
            printf("%s\t\t科目1\n",STU[i].Name);
        }
        if(STU[i].Score2<60)//学科2不及格时
        {
            UploadFail(STU[i].Name,"科目2");
            printf("%s\t\t科目2\n",STU[i].Name);
        }
        if(STU[i].Score3<60)//学科3不及格时
        {
            UploadFail(STU[i].Name,"科目3");
            printf("%s\t\t科目3\n",STU[i].Name);
        }
        if(STU[i].Score4<60)//学科4不及格时
        {
            UploadFail(STU[i].Name,"科目4");
            printf("%s\t\t科目4\n",STU[i].Name);
        }
    }
    printf("==============<分割线>====================\n\n");
    return OK;
}
int ScoreFail(int N)//打印指定科目不及格的学生
{//因为Fail函数已经实现了打印所有不及格的学生名单,在此函数仅提供显示指定科目不及格的学生
    while(1)
    {
        printf("------------------------------------\n");
        printf("|       0. 返回主菜单              |\n");
        printf("|       1. 打印科目1不及格的学生   |\n");
        printf("|       2. 打印科目2不及格的学生   |\n");
        printf("|       3. 打印科目3不及格的学生   |\n");
        printf("|       4. 打印科目4不及格的学生   |\n");
        printf("------------------------------------\n");
        int fox;//临时变量
        int i;
        int sum=0;
        scanf("%d",&fox);
        if(fox!=1&&fox!=2&&fox!=3&&fox!=4) break;//返回主菜单
        for(i=1;i<=N;i++)//打印不及格学生
        {
            int flag=0;//当flag=1时表示该同学有不及格的科目
            if(fox==1&&STU[i].Score1<60)//科目1不及格
            {
                printf("%s ",STU[i].Name);
                flag=1;
                sum++;
            }
            if(fox==2&&STU[i].Score2<60)//科目2不及格
            {
                printf("%s ",STU[i].Name);
                flag=1;
                sum++;
            }
            if(fox==3&&STU[i].Score3<60)//科目3不及格
            {
                printf("%s ",STU[i].Name);
                flag=1;
                sum++;
            }
            if(fox==4&&STU[i].Score4<60)//科目4不及格
            {
                printf("%s ",STU[i].Name);
                flag=1;
                sum++;
            }
            if(sum%5==0&&flag==1)//每五个学生为一组且仅当该学生某科目不及格时换行
                printf("\n");
        }
        printf("\n显示完成!\n");
    }
    return OK;
}

代码+题目

下载链接
提取码: h71s

发布了21 篇原创文章 · 获赞 10 · 访问量 4550

猜你喜欢

转载自blog.csdn.net/smallfox233/article/details/105086499