//各种分数结构体
struct scores
{
int Chinese;//语文
int Math;//数学
int English;//英语
int total;//总分
int aver;//平均分
};
//单个学生的基本信息结构体
struct student
{
char num[10];//学号
char name[12];//姓名
char sex[8];//性别
int age;//年龄
struct scores fenshu;//分数
char hobby[20];//爱好
};
//班级学生基本情况结构体
struct students
{
struct student* NUM [maxsize];//存放学生信息的数组
int length;//当前的班级学生的人数
};
//返回菜单结构体
struct laststep
{
struct students* NUM [process];//存放操作过程的数组
int length;//当前的操作步数
int i;//判断是否执行返回操作的标志
int current_index;//始终和length保持同步,只有当执行返回操作时,不再和length保持同步,
//作用是在之前的操作范围内返回,不返回当前的返回操作
int index;//当前的正在执行的返回操作的下标位置
};
//保存学生的人数
void save_num(students *first)
{
FILE *fp;
if((fp=fopen("total.txt","w"))==NULL)
{
printf("文件不存在,\n");
exit(0);
}
fprintf(fp,"%d",first->length);
fclose(fp);
}
//加载学生数据后,按照程序正常退出后,保存数据
void save(students *first)
{
FILE *fp;
if((fp=fopen("student.txt","w"))==NULL)
{
printf("文件不存在,\n");
exit(0);
}
printf("学生人数:%d\n",first->length);
for(int i=0;i<first->length;i++)
{
//first->NUM[i]=(student*)malloc(sizeof(student));
// fscanf(first->NUM[i],"%s%s%s%d%d%d%d%d%d%s",first->NUM[i]->num,first->NUM[i]->name,first->NUM[i]->sex,
// &(first->NUM[i]->age),&(first->NUM[i]->fenshu.Chinese),&(first->NUM[i]->fenshu.Math),&(first->NUM[i]->fenshu.English),
// &(first->NUM[i]->fenshu.total),&(first->NUM[i]->fenshu.aver),first->NUM[i]->hobby);
fprintf(fp,"%s\t%s\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%s\n",first->NUM[i]->num,first->NUM[i]->name,first->NUM[i]->sex,
first->NUM[i]->age,first->NUM[i]->fenshu.Chinese,first->NUM[i]->fenshu.Math,first->NUM[i]->fenshu.English,
first->NUM[i]->fenshu.total,first->NUM[i]->fenshu.aver,first->NUM[i]->hobby);
//fprintf(fp,"\n");
}
save_num(first);
printf("保存完毕!\n");
fclose(fp);
}
对文件操作不熟悉的话可以参考项目里的文件:c语言操作文件的说明
//通过学号修改信息
void alter_num2(laststep* record,students *first)
//学号修改信息循环步骤
students* alter_num(laststep* record,students *first)
//初始化班级信息
students* ChuShiHua(students *first)
//初始化返回记录信息
laststep* ChuShiHua_laststep(laststep *record)
//按照年龄删除
void delete_age(laststep* record,students * first)
//年龄删除中间步骤
int delete_age1(students *first,int &age,int &n)//传参数的时候整型和类似整型的其他类型的记得取地址符号,你自己就是因为没有取地址符号就吃亏了,调试了将近两个小时!!!!
//按照平均分删除
void delete_aver(laststep* record,students * first)
//平均分删除中间步骤
int delete_aver1(students *first,int &aver,int &n)//传参数的时候整型和类似整型的其他类型的记得取地址符号,你自己就是因为没有取地址符号就吃亏了,调试了将近两个小时!!!!
//按照语文分数删除
void delete_Chinese(laststep* record,students * first)
//语文分数删除中间步骤
int delete_Chinese1(students *first,int &Chinese,int &n)//传参数的时候整型和类似整型的其他类型的记得取地址符号,你自己就是因为没有取地址符号就吃亏了,调试了将近两个小时!!!!
//按照英语分数删除
void delete_English(laststep* record,students * first)
//英语分数删除中间步骤
int delete_English1(students *first,int &English,int &n)//传参数的时候整型和类似整型的其他类型的记得取地址符号,你自己就是因为没有取地址符号就吃亏了,调试了将近两个小时!!!!
//按照爱好删除
void delete_hobby(laststep* record,students * first)
//爱好删除中间步骤
int delete_hobby1(students *first,char hobby2[10],int &n)//传参数的时候整型和类似整型的其他类型的记得取地址符号,你自己就是因为没有取地址符号就吃亏了,调试了将近两个小时!!!!
//按照数学分数删除
void delete_Math(laststep* record,students * first)
//数学分数删除中间步骤
int delete_Math1(students *first,int &Math,int &n)//传参数的时候整型和类似整型的其他类型的记得取地址符号,你自己就是因为没有取地址符号就吃亏了,调试了将近两个小时!!!!
//删除菜单
void delete_menu(laststep*record,students *first)
//删除分数菜单
void delete_menu_scores(laststep*record,students *first)
//按照姓名删除
void delete_name(laststep* record,students * first)
//姓名删除中间步骤
int delete_name1(students *first,char name2[10],int &n)//传参数的时候整型和类似整型的其他类型的记得取地址符号,你自己就是因为没有取地址符号就吃亏了,调试了将近两个小时!!!!
//按照学号删除学生信息
void delete_num(laststep* record,students * first)
//按照性别删除
void delete_sex(laststep* record,students * first)
//性别删除中间步骤
int delete_sex1(students *first,char sex2[10],int &n)//传参数的时候整型和类似整型的其他类型的记得取地址符号,你自己就是因为没有取地址符号就吃亏了,调试了将近两个小时!!!!
//按照总分删除
void delete_total(laststep* record,students * first)
//总分删除中间步骤
int delete_total1(students *first,int &total,int &n)//传参数的时候整型和类似整型的其他类型的记得取地址符号,你自己就是因为没有取地址符号就吃亏了,调试了将近两个小时!!!!
//判断当前人数是否为空
void empty(students * first)
//将first的内容复制到记录中
void first_to_record(laststep* record,students *first)
//获取当前的学生人数
void gettotalnum(students * first)
//加载数据,其他的信息可以重复相同,但是学号不能重复!
//此算法只是初步的判断,如果用户一开始输入想输入的学号没有重复,但是实际上输入的与一开始将要输入的不一样,也可能输入成功!
students* jiazaishuju(laststep* record,students *first)
//加载数据中间步骤
students* jiazaishuju2(laststep* record,students *first)
//上一步
void last(laststep* record,students *first)
//返回菜单
void laststep_menu(laststep* record,students *first)
//初始化读取文件内容
//特别注意格式和对应的下标,同时注意是否要在前面取地址符号
void logo(students *first)
//读取文件里学生的人数
int logo_num(students *first)
//程序入口
int main()
//主菜单
void menu()
//下一步
void next(laststep* record,students *first)
//打印全部学生信息
void printall(students * first)
//记录操作步骤,有数据更新的地方都要使用一下,把数据记录下来,这里使用的是,定义一个相同的结构体,复制当前状态的
//信息。比如加入数据,删除数据,更改数据,重排数据都要记录下来
/*在加入撤退功能时,大部分的方法要加入laststep*record的参数,同时在调用这些方法的地方,也要加入参数,切记,你自己就犯了这个错误
改了比较久的时间
*/
void record_method(laststep* record,students *first)
//将记录中的内容放入到first中取
void record_to_first(laststep* record,students *first)
//按照年龄查找
void reserach_age(students * first)
// 按照平均分查找
void reserach_aver(students * first)
//按照语文分数查找
void reserach_Chinese(students * first)
// 按照英语分数查找
void reserach_English(students * first)
//按照爱好查找
void reserach_hobby(students * first)
//按照数学分数查找
void reserach_Math(students * first)
//查找菜单
void reserach_menu(students *first)
//分数查找菜单
void reserach_menu_scores(students *first)
//按照姓名查询
void reserach_name(students * first)
//按照学号查询
void reserach_num(students * first)
//按照 性别查找
void reserach_sex(students * first)
//按照总分数查找
void reserach_total(students * first)
//加载学生数据后,按照程序正常退出后,保存数据
void save(students *first)
//保存学生的人数
void save_num(students *first)
//按照年龄排序
void sort_age(students *first)
//按照平均分排序
void sort_aver(students *first)
//按照语文分数排序
void sort_Chinese(students *first)
//按照英语分数排序
void sort_English(students *first)
//按照爱好排序
void sort_hobby(students *first)
//按照数学分数排序
void sort_Math(students *first)
//排序菜单
void sort_menu(students *first)
//分数排序菜单
void sort_menu_scores(students *first)
//按照姓名排序
void sort_name(students *first)
//按照学号排序
void sort_num(students *first)
//按照性别排序
void sort_sex(students *first)
//按照总分排序
void sort_total(students *first)
主要使用的是C语言
开发工具是DEVC++
使用到了C语言中主要的知识点:
1.结构体
2.文件的读取和写入
3.基本的if,for,while,switch case等逻辑
4.使用到了动态的内存扩展:malloc
5.指针
int delete_aver1(students *first,int &aver,int &n)//传参数的时候整型和类似整型的其他类型的记得取地址符号,你自己就是因为没有取地址符号就吃亏了,调试了将近两个小时!!!!
record->NUM[record->length]->NUM[i]=(student*)malloc(sizeof(student));//记得要申请对应的学生空间
strcpy(record->NUM[record->length]->NUM[i]->num,first->NUM[i]->num);//字符数组不能直接用“=”赋值,要通过方法strcpy赋值,切记!!!
//加载数据,其他的信息可以重复相同,但是学号不能重复!
//此算法只是初步的判断,如果用户一开始输入想输入的学号没有重复,但是实际上输入的与一开始将要输入的不一样,也可能输入成功!
students* jiazaishuju(laststep* record,students *first)
//记录操作步骤,有数据更新的地方都要使用一下,把数据记录下来,这里使用的是,定义一个相同的结构体,复制当前状态的
//信息。比如加入数据,删除数据,更改数据,重排数据都要记录下来
/*在加入撤退功能时,大部分的方法要加入laststep*record的参数,同时在调用这些方法的地方,也要加入参数,切记,你自己就犯了这个错误
改了比较久的时间
*/
//初始化读取文件内容
//特别注意格式和对应的下标,同时注意是否要在前面取地址符号
//上一步
void last(laststep* record,students *first)
{
if(record->i==0)
{
record->current_index=record->length-1;
record->index=record->current_index;
record->i=1;
}
if(record->index<=0)
{
printf("到达后退的极限!\n");
return;
}
record->index--;
//first=record->NUM[record->index];//不能单纯的将指针赋值,因为他值得位置都是first,first的内容变了,复制的内容也会同步变动,所以返回步骤里的内容都是一样的
record_to_first(record,first);
//要解决这个问题就要将内容复制,你这里就是犯了这个错误所以失败了的,切记!!!
//printf("%d\n",first);
//printf("%d\n",record->NUM[record->index]);
save(first);
printall(first);
//record_method(record,first);//不注释的话,连带后退的过程也记录在内,注释后只记录其他真正的操作过程
}
如果对该项目由疑问的或者不能够理解的,再或者导入项目运行不成功的可以通过以下方式联系笔者!
1.电话号码:13870873449
2.qq:1056015243
3.邮箱地址:[email protected]
4.github地址:https://github.com/fanda521/StudentManagerSystem
时间 | 完成功能 |
---|---|
2018年1月1日 | 开始设计项目功能及初步的架构 |
2018年1月4日 | 完成数据结构的设计和增删查改 |
2018年1月6日 | 实现排序输出 |
2018年1月8日 | 实现文件读取保存 |
2018年1月10日 | 实现回撤与前进功能 |
https://github.com/fanda521/StudentManagerSystem/