由于代码量超过了百度知道答题的字数上限,下面只给出了部分代码,完整代码我已上传到百度网盘,请自行下载。下载链接:(点击下载)成绩管理程序。
30个学生的数据要手动输入,我已手动输入,测试通过。下面是测试结果。你自己测试的时候需要重新输入!输入学号的时候可以不按顺序输,这样更能体现程序的排序功能。排序的算法是简单的,也就是说效率不怎么样,但对新手来说,到这个程度就好。
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <conio.h>
#define mcr__stu_name_max_len 30
#define mcr__stu_inf_file_name ("stu_inf.dat") //保存学生信息的文件
#define mcr__new(data_type) (data_type*)malloc(sizeof(data_type))
typedef struct _Student
{
unsigned long ulng_stu_num; //学号
char chr1_stu_name[mcr__stu_name_max_len + 1]; //学生姓名
int int_scores; //C语言成成绩
struct _Student* next;
} Student;
typedef struct _RankStudent
{
Student stu_inf;
int ranking; //该学生的排名
struct _RankStudent* next;
} RankStudent;
void SwapRankStudent(RankStudent* p_1, RankStudent* p_2)
{
char chr1_name[mcr__stu_name_max_len + 1];
int scores, ranking;
unsigned long stu_num;
strcpy(chr1_name, p_1->stu_inf.chr1_stu_name);
strcpy(p_1->stu_inf.chr1_stu_name, p_2->stu_inf.chr1_stu_name);
strcpy(p_2->stu_inf.chr1_stu_name, chr1_name);
scores = p_1->stu_inf.int_scores;
p_1->stu_inf.int_scores = p_2->stu_inf.int_scores;
p_2->stu_inf.int_scores = scores;
stu_num = p_1->stu_inf.ulng_stu_num;
p_1->stu_inf.ulng_stu_num = p_2->stu_inf.ulng_stu_num;
p_2->stu_inf.ulng_stu_num = stu_num;
ranking = p_1->ranking;
p_1->ranking = p_2->ranking;
p_2->ranking = ranking;
}
long GetStudentDataSize()
{
return sizeof(unsigned long) + (sizeof(char) * (mcr__stu_name_max_len + 1)) + sizeof(int);
}
void ClearScreen() //清屏
{
system("cls");
}
void Pause() //暂停
{
_getch();
}
void RealseMemory(Student* p_stu_head) //释放动态申请的内存
{
Student* p_stu_remove;
while (p_stu_head)
{
p_stu_remove = p_stu_head;
p_stu_head = p_stu_head->next;
free(p_stu_remove);
}
}
void RealseMemory_2(RankStudent* p_stu_head)
{
RankStudent* p_stu_remove;
while (p_stu_head)
{
p_stu_remove = p_stu_head;
p_stu_head = p_stu_head->next;
free(p_stu_remove);
}
}
/* 处理文件的部分 */
int AppendStuInfToFile(Student* p_stu_head) //向文件尾部追加若干数据,返回0表示操作失败。
{
if (p_stu_head == NULL)
{
return 0;
}
FILE* p_file = fopen(mcr__stu_inf_file_name, "a");
if (p_file == NULL)
{
return 0;
}
while (p_stu_head)
{
fwrite(&p_stu_head->ulng_stu_num, sizeof(unsigned long), 1, p_file);
fwrite(p_stu_head->chr1_stu_name, sizeof(char), mcr__stu_name_max_len + 1, p_file);
fwrite(&p_stu_head->int_scores, sizeof(int), 1, p_file);
p_stu_head = p_stu_head->next;
}
fclose(p_file);
return 1;
}
RankStudent* GetStuInfFromFile() //参数返回获取的学生信息的数目
{
FILE* p_file = fopen(mcr__stu_inf_file_name, "r");
if (p_file == NULL)
{
printf("文件打开失败,按任意键返回主菜单!");
Pause();
ClearScreen();
return NULL;
}
RankStudent *p_stu_head = NULL, *p_stu_cur, *p_stu_new;
p_stu_new = p_stu_cur = p_stu_head = mcr__new(RankStudent);
p_stu_new->next = NULL;
fread(&p_stu_new->stu_inf.ulng_stu_num, sizeof(unsigned long), 1, p_file);
fread(p_stu_new->stu_inf.chr1_stu_name, sizeof(char), mcr__stu_name_max_len + 1, p_file);
fread(&p_stu_new->stu_inf.int_scores, sizeof(int), 1, p_file);
while (1)
{
p_stu_new = mcr__new(RankStudent);
p_stu_new->next = NULL;
fread(&p_stu_new->stu_inf.ulng_stu_num, sizeof(unsigned long), 1, p_file);
fread(p_stu_new->stu_inf.chr1_stu_name, sizeof(char), mcr__stu_name_max_len + 1, p_file);
if (fread(&p_stu_new->stu_inf.int_scores, sizeof(int), 1, p_file) <= 0)
{
break;
}
p_stu_cur->next = p_stu_new;
p_stu_cur = p_stu_new;
}
fclose(p_file);
return p_stu_head;
}
/* 界面 */
int MainUI() //主界面
{
printf(" C语言成绩管理\n\n\n");
printf(" 1.增加新信息\n");
printf(" 2.修改信息\n");
printf(" 3.查询信息\n");
printf(" 4.显示60分以下学生的信息\n");
printf(" 5.显示分数在60至79之间的学生的信息\n");
printf(" 6.显示分数在80至89之间的学生的信息\n");
printf(" 7.显示90分以上学生的信息\n");
printf(" 8.显示及格率和平均分,最高分和最低分\n");
printf(" 9.显示所有学生排名(按学号排序)\n");
printf(" 10.退出\n\n");
printf(" 输入对应的序号来选择相应的选项: ");
int num = 9;
scanf("%d", &num);
return num;
}
void AppendInfUI() //增加新信息界面
{
int count; //将要输入的信息条数
printf("你要输入多少条学生信息?在此输入数目: ");
scanf("%d", &count);
if (count <= 0)
{
printf("输入数目不能小于或等于0!输入错误,按任意键返回主菜单。");
Pause();
ClearScreen();
return; //输入不合理的数目,将退出该界面。
}
Student *p_stu_new, *p_stu_head, *p_stu_cur;
int count_tmp = 1;
printf("共要输入%d条信息,这是第%d条\n", count, count_tmp);
p_stu_cur = p_stu_head = p_stu_new = mcr__new(Student);
p_stu_new->next = NULL;
printf("姓名: ");
scanf("%s", p_stu_new->chr1_stu_name);
printf("学号: ");
scanf("%d", &p_stu_new->ulng_stu_num);
printf("分数: ");
scanf("%d", &p_stu_new->int_scores);
ClearScreen();
for (++ count_tmp; count_tmp <= count; count_tmp ++)
{
printf("共要输入%d条信息,这是第%d条\n", count, count_tmp);
p_stu_new = mcr__new(Student);
p_stu_new->next = NULL;
printf("姓名: ");
scanf("%s", p_stu_new->chr1_stu_name);
printf("学号: ");
scanf("%lu", &p_stu_new->ulng_stu_num);
printf("分数: ");
scanf("%d", &p_stu_new->int_scores);
p_stu_cur->next = p_stu_new;
p_stu_cur = p_stu_new;
ClearScreen();
}
if (AppendStuInfToFile(p_stu_head)) //返回真,表示保存成功。
{
printf("数据已保存,按任意键回主菜单!");
}
else
{
printf("数据保存失败,按任意键回主菜单!");
}
RealseMemory(p_stu_head);
Pause();
ClearScreen();
}
/*
* 修改信息界面。如果开放按姓名修改信息的方法,
* 那么如果有重名的学生,界面将更加复杂。所以
* 没必要按姓名修改。其实在查询信息的界面开放
* 了“按姓名查找”;可以在修改数据之前,先去按
* 姓名查找一下,以得到学号,然后再去修改信息。
*/
void ModifyInfUI()
{
unsigned long stu_num;
printf("请输入你要修改的学生的信息的学号: ");
scanf("%lu", &stu_num); //输入unsigned long的格式为 %lu
FILE* p_file = fopen(mcr__stu_inf_file_name, "r+"); //可读可写方式打开文件
if (p_file == NULL)
{
printf("文件打开失败,按任意键返回主菜单!");
Pause();
ClearScreen();
return;
}
long stu_data_size = GetStudentDataSize();
Student stu;
while (!feof(p_file))
{
fread(&stu.ulng_stu_num, sizeof(unsigned long), 1, p_file);
fread(stu.chr1_stu_name, sizeof(char), mcr__stu_name_max_len + 1, p_file);
fread(&stu.int_scores, sizeof(int), 1, p_file);
if (stu.ulng_stu_num == stu_num)
{
printf("学号为%lu的学生的信息如下\n", stu_num);
printf("姓名: %s\n", stu.chr1_stu_name);
printf("学号: %lu\n", stu.ulng_stu_num);
printf("分数: %d\n\n", stu.int_scores);
printf("请输入新的信息,如果不想修改某项内容,那么将原来的内容填上即可。\n");
printf("新姓名: ");
scanf("%s", stu.chr1_stu_name);
printf("新学号: ");
scanf("%lu", &stu.ulng_stu_num);
printf("新分数: ");
scanf("%d", &stu.int_scores);
fseek(p_file, -1 * stu_data_size, SEEK_CUR); //跑到该数据之前
//用新数据覆盖旧数据
fwrite(&stu.ulng_stu_num, sizeof(unsigned long), 1, p_file);
fwrite(stu.chr1_stu_name, sizeof(char), mcr__stu_name_max_len + 1, p_file);
fwrite(&stu.int_scores, sizeof(int), 1, p_file);
fclose(p_file);
printf("修改成功,按任意键返回主菜单。");
Pause();
ClearScreen();
return;
}
}
fclose(p_file);
printf("当前没有找到学号为%lu的学生的信息,按任意键返回主菜单。\n", stu_num);
Pause();
ClearScreen();
}
void SearchInfUI() //查询信息界面
{
int num = 1;
printf("1.按学号查找。\n\n");
printf("2.按姓名查找。\n\n");
printf("请在此输入你的选择: ");
scanf("%d", &num);
if (num == 1) //按学号查找
{
unsigned long stu_num;
printf("请输入你要查找的学生的信息的学号: ");
scanf("%lu", &stu_num); //输入unsigned long的格式为 %lu
FILE* p_file = fopen(mcr__stu_inf_file_name, "r");
if (p_file == NULL)
{
printf("文件打开失败,按任意键返回主菜单!");
Pause();
ClearScreen();
return;
}
long stu_data_size = GetStudentDataSize();
Student stu;
while (!feof(p_file))
{
fread(&stu.ulng_stu_num, sizeof(unsigned long), 1, p_file);
fread(stu.chr1_stu_name, sizeof(char), mcr__stu_name_max_len + 1, p_file);
fread(&stu.int_scores, sizeof(int), 1, p_file);
if (stu.ulng_stu_num == stu_num)
{
printf("学号为%lu的学生的信息如下\n", stu_num);
printf("姓名: %s\n", stu.chr1_stu_name);
printf("学号: %lu\n", stu.ulng_stu_num);
printf("分数: %d\n\n", stu.int_scores);
printf("按任意键返回主菜单。");
Pause();
ClearScreen();
return;
}
}
fclose(p_file);
printf("当前没有找到学号为%lu的学生的信息,按任意键返回主菜单。\n", stu_num);
Pause();
ClearScreen();
}
else if (num == 2)//按姓名查找
{
char chr1_name[mcr__stu_name_max_len + 1];
int count = 0;
printf("请输入你要查找的学生的信息的姓名: ");
scanf("%s", chr1_name);
FILE* p_file = fopen(mcr__stu_inf_file_name, "r");
if (p_file == NULL)
{
printf("文件打开失败,按任意键返回主菜单!");
Pause();
ClearScreen();
return;
}
long stu_data_size = GetStudentDataSize();
Student stu;
while (1) //用!feof(p_file)作判断会多跑一次
{
fread(&stu.ulng_stu_num, sizeof(unsigned long), 1, p_file);
fread(stu.chr1_stu_name, sizeof(char), mcr__stu_name_max_len + 1, p_file);
if (fread(&stu.int_scores, sizeof(int), 1, p_file) <= 0)
{
break;
}
if (strcmp(stu.chr1_stu_name, chr1_name) == 0)
{
printf("姓名: %s\n", stu.chr1_stu_name);
printf("学号: %lu\n", stu.ulng_stu_num);
printf("分数: %d\n\n", stu.int_scores);
count ++;
}
}
fclose(p_file);
printf("共找到%d个结果,按任意键返回主菜单。", count);
Pause();
ClearScreen();
}
else
{
printf("没有这个选项,按任意键返回主菜单。");
Pause();
ClearScreen();
}
}
void ScoresUI(int min, int max) //显示分数在min到max之间的学生的信息
{
int count = 0;
FILE* p_file = fopen(mcr__stu_inf_file_name, "r");
if (p_file == NULL)
{
printf("文件打开失败,按任意键返回主菜单!");
Pause();
ClearScreen();
return;
}