实验内容: 编写并调试程序,实现学校各专业班级学生信息的管理。定义学生信息的结构体类型,包括:学号、姓名、专业、班级、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();
}