用C语言实现学生信息管理系统

实验内容: 编写并调试程序,实现学校各专业班级学生信息的管理。定义学生信息的结构体类型,包括:学号、姓名、专业、班级、3门成绩。定义N名学生信息的结构体数组。
实验要求:
(1) main函数:以菜单形式将各项功能提供给用户,根据用户的选择,调用相应的函数。
(2) 定义函数Input:从键盘输入一个学生信息。
(3) 定义函数Output:将某个学生信息格式化输出。
(4) 定义函数Save:将某个学生信息存入文件。
(5) 定义函数Fetch:从文件中读取某个学生的信息(按学号或位置输出学生的信息)。
(6) 定义函数Max:求所有学生某门课程的最高分和分数最高的学生的姓名。
(7) 定义函数Sort_select:对某个专业的学生,按总平均成绩由低到高进行选择排序。
(8) 定义函数Sort_buble:对某个班级的学生,按总平均成绩由高到低进行起泡排序。
(9) 定义函数Sort_insert:对某个班级的学生,按某门课程成绩由低到高进行直接插入排序。
(10) 定义函数Search:实现班级和成绩的综合查找(如1班,总分240分以上同学)。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define N 10

int menu(void);  //菜单函数
void choose(void);  //选择选项函数
void Input(void);
void Output(void);
void Save(void);
void Fetch(void);
void Max(void);
void Sort_select(void);
void Sort_buble(void);
void Sort_insert(void);
void Search(void);

struct student
{
    int No;   //学号
    char name[10];
    char major[10];  //专业
    char cla[5];  //班级
    int CScore;  //C语言成绩
    int EScore;  //英语成绩
    int MScore;  //数学成绩
}stu[N];

struct sco_stu  //排序时用到
{
    int No;
    char name[10];
    int average;
};

int menu(void)
{
    int mchoice;
    printf("********************菜单********************\n\n");
    printf("0、退出程序\n");
    printf("1、输入学生信息\n");
    printf("2、输出学生信息\n");
    printf("3、保存学生信息到文件\n");
    printf("4、从文件中随机读取一个学生信息\n");
    printf("5、求所有学生某门课程的最高分和分数最高的学生的姓名\n");
    printf("6、对某个专业的学生,按总平均成绩由低到高进行简单选择排序\n");
    printf("7、对某个班级的学生,按总平均成绩由高到低进行起泡排序\n");
    printf("8、对某个班级的学生,按某门课程成绩由低到高进行直接插入排序\n");
    printf("9、实现班级和成绩的综合查找\n");
    printf("---------------------------------------------------------------\n");
 
    printf("请输入选项:");
    scanf("%d", &mchoice);
    printf("\n");
    while(mchoice > 9)  //当输入超过9时需要重新输入正确的数据
    {
        printf("请输入0-9:");
        scanf("%d", &mchoice);
    }
    return mchoice;
}

void choose(void)
{
    int choice;
    choice = menu();
    while(0 <= choice && choice <= 9)
    {
        switch(choice)
        {
        case 1:
             Input();
            break;
        case 2:
            Output();
            break;
        case 3:
            Save();
            break;
        case 4:
            Fetch();
            break;
        case 5:
            Max();
            break;
        case 6:
            Sort_select();
            break;
        case 7:
            Sort_buble();
            break;
        case 8:
            Sort_insert();
            break;
        case 9:
            Search();
            break;
        case 0:
            printf("已退出程序\n");
            exit(0);
        }
        choice = menu();
    }
}

void Input(void)
{
    int i,en;
    for(i = 0; i < N; i++)
    {
        if(stu[i].No == 0)  //学号为0时说明该单元为空,才能存入信息,否则进行+1操作,查询下一个单元是否为空
        {
            printf("输入信息请按1,停止输入请按0\n");   //可以随时继续输入信息或者停止输入
            scanf("%d", &en);
            
            if(en == 0)
                return;
            else
            {
                printf("请输入以下信息:\n");
                printf("学号(1-100):");
                scanf("%d", &stu[i].No);
                printf("姓名:");
                scanf("%s", stu[i].name);
                printf("专业:");
                scanf("%s", stu[i].major);
                printf("班级:");
                scanf("%s", stu[i].cla);
                printf("C语言成绩:");
                scanf("%d", &stu[i].CScore);
                printf("英语成绩:");
                scanf("%d", &stu[i].EScore);
                printf("数学成绩:");
                scanf("%d", &stu[i].MScore);
                printf("\n");
            }
        }
    }
}

void Output(void)
{
    int i;
    int flag = 0;  //flag为错误提示
    int no;
    printf("请输入要输出信息的学生学号:");
    scanf("%d", &no);
    for(i = 0; i < N; i++)
    {
        if(stu[i].No == no)
        {
            printf("学号:%d\n", stu[i].No);
            printf("姓名:%s\n", stu[i].name);
            printf("专业:%s\n", stu[i].major);
            printf("班级:%s\n", stu[i].cla);
            printf("C语言成绩:%d\n", stu[i].CScore);
            printf("英语成绩:%d\n", stu[i].EScore);
            printf("数学成绩:%d\n", stu[i].MScore);
            printf("\n");
            flag++;
        }
    }
        
    if(flag == 0)  //当查找完整个数组后没有找到学生信息时,flag为0,则报错
    {
        printf("没有该学生学号,需要重新输入学号\n\n");
        Output();
    }
}

void Save(void)
{
    FILE *fp;
    int i, sno;
    int flag = 0;  //错误标志位
    fp = fopen("manager", "a");  //已附加方式打开只写文件,写入的文件会被加到文件尾
    printf("请输入要保存进文档里的学生信息学号:");
    scanf("%d", &sno);
    for(i = 0; i < N; i++)
    {
        if(stu[i].No == sno)
        {
            fwrite(&stu[i],sizeof(struct student), 1, fp);
            stu[i].No = 0;
            printf("已保存\n\n");
            flag++;
        }
    }
    
    if(flag == 0)
    {
        printf("没有该学生学号,需要重新输入\n\n");
        Save();
    }
    fclose(fp);
}

void Fetch(void)
{
    FILE *fp;
    int i, ret;
    int flag = 0;
    struct student stu1[N];  //创建新的数组用来保存从文件中读取的数据
    
    for(i = 0; i < N; i++)  //将stu1数组所有单元的学号置为0,标志为空
        {
           stu1[i].No = 0;
        }

    fp = fopen("manager", "r");
    fread(stu1, sizeof(struct student), N, fp);
    fclose(fp);

    for(i = 0; i < N; i++)  //计算文件中有几个学生信息
    {
        if(stu1[i].No != 0)
            flag++;
    }

    if(flag == 0)
    {
        printf("文件中没有学生信息,请先输入学生信息");
    }
    else
    {
        srand(time(NULL));
        ret = rand()%flag;  //生成随机数
        ret = ret + 1;  //rand()生成的是从0-(flag-1)的随机数,而ret不能为0,故进行加一操作

        for(i = 0; i < N; i++)
        {
            if(stu1[i].No == ret)
            {
                printf("学号:%d\n", stu1[i].No);
                printf("姓名:%s\n", stu1[i].name);
                printf("专业:%s\n", stu1[i].major);
                printf("班级:%s\n", stu1[i].cla);
                printf("C语言成绩:%d\n", stu1[i].CScore);
                printf("英语成绩:%d\n", stu1[i].EScore);
                printf("数学成绩:%d\n", stu1[i].MScore);
                printf("\n");
            }
        }
    }
}

void Max(void)
{
    int i, j, maxs, en;
    char name[10];
    FILE *fp;
    struct student stu2[N];  //创建新的数组用来保存从文件中读取的数据

    for(i = 0; i < N; i++)
    {
       stu2[i].No = 0;
    }

    fp = fopen("manager", "r");
    fread(stu2, sizeof(struct student), N, fp);
    fclose(fp);

    printf("1、C语言\n");
    printf("2、英语\n");
    printf("3、数学\n");
    printf("请选择课程(1-3):");
    scanf("%d", &en);
    printf("\n");

    if(en == 1)
    {
        maxs = stu2[0].CScore;
        for(j = 0; j < 10; j++)
        {
            name[j] = stu2[0].name[j];
        }
        for(i = 1; i < N; i++)   //先找到文件中的分数最高
        {
            if(stu2[i].No != 0)
            {
                if(stu2[i].CScore > maxs)
                {
                    maxs = stu2[i].CScore;
                    for(j = 0; j < 10; j++)
                    {
                        name[j] = stu2[i].name[j];
                    }
                }
            }
        }
       for(i = 0; i < N; i++)   //再与刚输入的分数比较,找到最后的最高分
        {
            if(stu[i].No != 0)
            {
                if(stu[i].CScore > maxs)
                {
                    maxs = stu[i].CScore;
                    for(j = 0; j < 10; j++)
                    {
                        name[j] = stu[i].name[j];
                    }
                }
            }
        }
        printf("C语言最高分为:%d,学生名为:%s\n\n", maxs, name);
    }
    else if(en == 2)
    {
        maxs = stu2[0].EScore;
        for(j = 0; j < 10; j++)
        {
            name[j] = stu2[0].name[j];
        }
        for(i = 1; i < N; i++)
        {
            if(stu2[i].No != 0)
            {
                if(stu2[i].EScore > maxs)
                {
                    maxs = stu2[i].EScore;
                    for(j = 0; j < 10; j++)
                    {
                        name[j] = stu2[i].name[j];
                    }
                }
            }
        }
        for(i = 0; i < N; i++)   //再与刚输入的分数比较,找到最后的最高分
        {
            if(stu[i].No != 0)
            {
                if(stu[i].EScore > maxs)
                {
                    maxs = stu[i].EScore;
                    for(j = 0; j < 10; j++)
                    {
                        name[j] = stu[i].name[j];
                    }
                }
            }
        }
        printf("英语最高分为:%d,学生名为:%s\n\n", maxs, name);
    }
    else
    {
        maxs = stu2[0].MScore;
        for(j = 0; j < 10; j++)
        {
            name[j] = stu2[0].name[j];
        }
        for(i = 1; i < N; i++)
        {
            if(stu2[i].No != 0)
            {
                if(stu2[i].MScore > maxs)
                {
                    maxs = stu2[i].MScore;
                    for(j = 0; j < 10; j++)
                    {
                        name[j] = stu2[i].name[j];
                    }
                }
            }
        }
        for(i = 0; i < N; i++)   //再与刚输入的分数比较,找到最后的最高分
        {
            if(stu[i].No != 0)
            {
                if(stu[i].MScore > maxs)
                {
                    maxs = stu[i].MScore;
                    for(j = 0; j < 10; j++)
                    {
                        name[j] = stu[i].name[j];
                    }
                }
            }
        }
        printf("数学最高分为:%d,学生名为:%s\n\n", maxs, name);
    }
}

void Sort_select(void)
{
    int i, j, n = 0, flag = 0, small;
    FILE *fp;
    char major[10];
    
    struct student stu3[N];
    struct sco_stu sco1[N];
    struct sco_stu temp[1];
    
    for(i = 0; i < N; i++)
    {
       stu3[i].No = 0;
    }
    for(i = 0; i < N; i++)
    {
       sco1[i].No = 0;
    }
    fp = fopen("manager", "r");
    fread(stu3, sizeof(struct student), N, fp);   //先将文件中的所有信息读取到stu[3]中
    fclose(fp);
    
     for(i = 0; i < N; i++)  //再将新输入到stu[]中的信息也读取到stu3[]中
    {
        if(stu3[i].No == 0)
        {
            if(stu[n].No != 0)
            {
                stu3[i].No = stu[n].No;
                memcpy(stu3[i].name, stu[n].name, 10);
                memcpy(stu3[i].major, stu[n].major, 10);
                memcpy(stu3[i].cla, stu[n].cla, 5);
                stu3[i].CScore = stu[n].CScore;
                stu3[i].EScore = stu[n].EScore;
                stu3[i].MScore = stu[n].MScore;
                n++;
            }
        }
    }
    
    printf("请输入专业:");
    scanf("%s", major);
    for(i = 0; i < N; i++)
    {
        if(stu3[i].No != 0)
        {
            if(strcmp(stu3[i].major, major) == 0)  //将指定专业的学生信息存入sco1[]中
            {
                flag++;
                sco1[i].No = stu3[i].No;
                memcpy(sco1[i].name, stu3[i].name, 10);
                sco1[i].average = (stu3[i].CScore + stu3[i].EScore + stu3[i].MScore)/3;
            }
        }
    }
    
    if(flag != 0)   //简单选择排序
    {
        n = 0;
        for(i = n; i < N; i++)
        {
            if(sco1[i].No != 0)
            {
                small = i;
                for(j = i+1; j < N; j++)
                {
                    if(sco1[j].No != 0)
                    {
                        if(sco1[j].average < sco1[small].average)
                            small = j;
                    }
                }
                n++;
                
                if(small == i)
                    break;
                else
                {
                    temp[0].No = sco1[i].No;  //先把第一个数据给临时数组
                    memcpy(temp[0].name, sco1[i].name, 10);
                    temp[0].average = sco1[i].average;
                    
                    sco1[i].No = sco1[small].No;  //再把最小的数据放在第一位
                    memcpy(sco1[i].name, sco1[small].name, 10);
                    sco1[i].average = sco1[small].average;
                    
                    sco1[small].No = temp[0].No;  //最后把临时数组里的数据放回去
                    memcpy(sco1[small].name, temp[0].name, 10);
                    sco1[small].average = temp[0].average;
                }
            }
        }
        printf("按从小到大顺序排列:\n\n");
        for(i = 0; i < N; i++)
        {
            if(sco1[i].No != 0)
            {
                printf("姓名:%s", sco1[i].name);
                printf("  平均分:%d\n", sco1[i].average);
                printf("\n");
            }
        }
    }
    else
    {
        printf("没有该专业,需要重新专业。\n\n");
        Sort_select();
    }
}

void Sort_buble(void)
{
    int i, max, flag = 0, n = 0, num = 0;
    FILE *fp;
    char major[10], cla[5];
    
    struct student stu3[N];
    struct sco_stu sco1[N];
    struct sco_stu temp[1];
    
     for(i = 0; i < N; i++)
    {
       stu3[i].No = 0;
    }
    for(i = 0; i < N; i++)
    {
       sco1[i].No = 0;
    }
    fp = fopen("manager", "r");
    fread(stu3, sizeof(struct student), N, fp);   //先将文件中的所有信息读取到stu[3]中
    fclose(fp);
    
     for(i = 0; i < N; i++)  //再将新输入到stu[]中的信息也读取到stu3[]中
    {
        if(stu3[i].No == 0)
        {
            if(stu[n].No != 0)
            {
                stu3[i].No = stu[n].No;
                memcpy(stu3[i].name, stu[n].name, 10);
                memcpy(stu3[i].major, stu[n].major, 10);
                memcpy(stu3[i].cla, stu[n].cla, 5);
                stu3[i].CScore = stu[n].CScore;
                stu3[i].EScore = stu[n].EScore;
                stu3[i].MScore = stu[n].MScore;
                n++;
            }
        }
    }
    
     printf("请输入专业:");
    scanf("%s", major);
    printf("请输入班级:");
    scanf("%s", cla);
    for(i = 0; i < N; i++)
    {
        if(stu3[i].No != 0)
        {
            if((strcmp(stu3[i].major, major) == 0) && (strcmp(stu3[i].cla, cla) == 0))  //将指定专业和班级的学生信息存入sco1[]中
            {
                num++;
                sco1[i].No = stu3[i].No;
                memcpy(sco1[i].name, stu3[i].name, 10);
                sco1[i].average = (stu3[i].CScore + stu3[i].EScore + stu3[i].MScore)/3;
            }
        }
    }
    
    if(num == 0)   //起泡排序
    {
        printf("没有该专业班级的学生,需要重新输入。\n");
        Sort_buble();
    }
    else
    {
        for(flag = 0; flag < num; flag++)
        {
            max = num-1;
            if(max != 0)
            {
                for(i = num-2; i >= flag; i--)
                {
                    if(sco1[i].average > sco1[max].average)
                    {
                        max = i;
                    }
                    else
                    {
                        temp[0].No = sco1[i].No;  //将平均成绩小的数据放入临时数组
                        memcpy(temp[0].name, sco1[i].name, 10);
                        temp[0].average = sco1[i].average;
                        
                        sco1[i].No = sco1[max].No;  //将平均成绩大的数据往前移一位
                        memcpy(sco1[i].name, sco1[max].name, 10);
                        sco1[i].average = sco1[max].average;
                        
                        sco1[max].No = temp[0].No;  //将放在临时数组里的数据放回
                        memcpy(sco1[max].name, temp[0].name, 10);
                        sco1[max].average = temp[0].average;
                        
                        max = i;
                    }
                }
            }
        }
    }
    
    printf("按从大到小顺序排列:\n\n");
    for(i = 0; i < N; i++)
        {
            if(sco1[i].No != 0)
            {
                printf("姓名:%s\n", sco1[i].name);
                printf("平均分:%d\n", sco1[i].average);
                printf("\n");
            }
        }
}

void Sort_insert(void)
{
    int i, j, num = 0, n = 0;
    FILE *fp;
    char major[10], cla[5];
    
    struct student stu3[N];
    struct sco_stu sco1[N];
    struct sco_stu temp[1];
    
    for(i = 0; i < N; i++)
    {
       stu3[i].No = 0;
    }
    for(i = 0; i < N; i++)
    {
       sco1[i].No = 0;
    }
    fp = fopen("manager", "r");
    fread(stu3, sizeof(struct student), N, fp);   //先将文件中的所有信息读取到stu[3]中
    fclose(fp);
    
    for(i = 0; i < N; i++)  //再将新输入到stu[]中的信息也读取到stu3[]中
    {
        if(stu3[i].No == 0)
        {
            if(stu[n].No != 0)
            {
                stu3[i].No = stu[n].No;
                memcpy(stu3[i].name, stu[n].name, 10);
                memcpy(stu3[i].major, stu[n].major, 10);
                memcpy(stu3[i].cla, stu[n].cla, 5);
                stu3[i].CScore = stu[n].CScore;
                stu3[i].EScore = stu[n].EScore;
                stu3[i].MScore = stu[n].MScore;
                n++;
            }
        }
    }
    
    printf("请输入专业:");
    scanf("%s", major);
    printf("请输入班级:");
    scanf("%s", cla);
    printf("\n");
    for(i = 0; i < N; i++)
    {
        if(stu3[i].No != 0)
        {
            if((strcmp(stu3[i].major, major) == 0) && (strcmp(stu3[i].cla, cla) == 0))  //将指定专业和班级的学生信息存入sco1[]中
            {
                num++;
                sco1[i].No = stu3[i].No;
                memcpy(sco1[i].name, stu3[i].name, 10);
                sco1[i].average = (stu3[i].CScore + stu3[i].EScore + stu3[i].MScore)/3;
            }
        }
    }
    if(num != 0)
    {
        for(i = 1; i < num; i++)  //直接插入排序
        {
            j = i;
            temp[0].No = sco1[i].No;
            memcpy(temp[0].name, sco1[i].name, 10);
            temp[0].average = sco1[i].average;
            
             while(j > 0 && temp[0].average < sco1[j-1].average)
            {
                sco1[j].No = sco1[j-1].No;
                memcpy(sco1[j].name, sco1[j-1].name, 10);
                sco1[j].average = sco1[j-1].average;
                j--;
            }
            sco1[j].No = temp[0].No;
            memcpy(sco1[j].name, temp[0].name, 10);
            sco1[j].average = temp[0].average;
        }
        printf("按从小到大顺序排列:\n\n");
        for(i = 0; i < num; i++)
        {
            printf("姓名:%s", sco1[i].name);
            printf("  平均分:%d\n", sco1[i].average);
            printf("\n");
        }
    }
    else
    {
         printf("没有该专业,需要重新专业和班级。\n\n");
         Sort_insert();
 }

void Search(void)
{
    int i, score, flag = 0, num = 0, n = 0;
    FILE *fp;
    char major[10], cla[5];
    
    struct student stu3[N];
    struct sco_stu sco1[N];
    
    for(i = 0; i < N; i++)
    {
       stu3[i].No = 0;
    }
    for(i = 0; i < N; i++)
    {
       sco1[i].No = 0;
    }
    fp = fopen("manager", "r");
    fread(stu3, sizeof(struct student), N, fp);   //先将文件中的所有信息读取到stu[3]中
    fclose(fp);
    
    for(i = 0; i < N; i++)  //再将新输入到stu[]中的信息也读取到stu3[]中
    {
        if(stu3[i].No == 0)
        {
            if(stu[n].No != 0)
            {
                stu3[i].No = stu[n].No;
                memcpy(stu3[i].name, stu[n].name, 10);
                memcpy(stu3[i].major, stu[n].major, 10);
                memcpy(stu3[i].cla, stu[n].cla, 5);
                stu3[i].CScore = stu[n].CScore;
                stu3[i].EScore = stu[n].EScore;
                stu3[i].MScore = stu[n].MScore;
                n++;
            }
        }
    }
    
    printf("查找某班级总分超过一定分数的学生:\n");
    printf("请输入专业:");
    scanf("%s", major);
    printf("请输入班级:");
    scanf("%s", cla);
    for(i = 0; i < N; i++)
    {
        if(stu3[i].No != 0)
        {
            if((strcmp(stu3[i].major, major) == 0) && (strcmp(stu3[i].cla, cla) == 0))  //将指定专业和班级的学生信息存入sco1[]中
            {
                num++;
                sco1[i].No = stu3[i].No;
                memcpy(sco1[i].name, stu3[i].name, 10);
                sco1[i].average = stu3[i].CScore + stu3[i].EScore + stu3[i].MScore;
            }
        }
    }
    
    if(num != 0)
    {
        printf("请输入总分:");
        scanf("%d", &score);
        printf("\n");
        for(i = 0; i < num; i++)
        {
            if(sco1[i].average >= score)
            {
                flag++;
                printf("学号:%d\n", sco1[i].No);
                printf("姓名:%s\n", sco1[i].name);
                printf("总分:%d\n", sco1[i].average);
                printf("\n");
            }
        }
        
        if(flag == 0)
        {
            printf("该专业班级没有总分超过%d分的学生,需要重新输入。\n", score);
            Search();
        }
    }
    else
    {
        printf("没有该专业班级的学生,需要重新输入。\n");
        Search();
    }
}

int main()
{
    int n;
    for(n = 0; n < N; n++)  //将所有单元的学号置为0,标志为空
    {
       stu[n].No = 0;
    }
    choose();
}