c语言单向链表实现学生管理系统(加文件读写)
本项目为自己手写,希望可以帮助到各位,如果有什么不足大家可以在评论区评论
题目内容:
1、需求分析
学生纪录用文件存储,因而要提供文件的输入输出操作;要实现插入一个新的学生纪录,因而要提供文件的插入操作;要实现学生纪录得修改和删除,以及登记成绩和修改成绩,因而要提供文件纪录的修改和删除操作;要浏览全班成绩,故要提供显示操作;计算学生总成绩需要提供简单的统计操作;要按学号排序输出全班成绩表,因而要提供排序操作;另外要提供键盘式选择菜单以实现功能选择。
2、总体设计
整个成绩管理系统设计为数据插入模块、数据修改模块、数据删除模块、成绩登记模块、成绩修改模块、数据浏览模块、成绩统计模块、成绩表查看模块。
3、详细设计
数据结构采用结构体,设计学生纪录结构体:
typedef struct studentRecord
{
char stuNo[15]; //学号
char name[20]; //姓名
int age; //年龄
float math; //数学
float english; //英语
float physics; //物理
}SR;
(1)主函数输出提示菜单:插入学生纪录 修改学生纪录 删除学生纪录 登记成绩
修改成绩 浏览学生纪录 查看总成绩 查看成绩表
(2)数据插入模块
采用追加的方式用fwrite或fprintf把学生成绩信息写入学生成绩信息文件。
(3)数据修改模块
通过菜单选择修改学生纪录,用fopen打开该文件,从文件中读一条记录,判断是否要修改,如果是,则修改后重新写入文件;否则直接重新写入文件,读下一条记录。
(4)数据删除模块
通过菜单选择删除学生纪录,用fopen打开该文件,从文件中读一条记录,判断是否要删除,如果是,则舍弃;否则重新写入文件,读下一条记录。
(5)成绩登记模块
类似数据修改模块,只是修改字段为各个科目的成绩。
(6)成绩修改模块
参考数据修改模块。
(7)数据浏览模块
用fscanf或fread读取学生成绩信息文件,分屏输出,每屏10条纪录。
(8)成绩统计模块
用fscanf或fread从学生成绩信息文件中读取一个学生纪录,计算该学生的总成绩(简单的成绩相加),输出,然后读取下一条纪录。
(9)成绩表查看模块
建立结构体数组
struct
{
SR record; //学生纪录
float total; //总成绩
}stu[N];
从学生成绩信息文件中读取各个纪录,total中存放计算得到的总成绩。然后采用排序算法(冒泡、插入、选择等)对数组按照总成绩进行排序。最后顺序输出。
代码示例:
#include
#include
#include
#include
typedef struct studentRecord
{char stuNo[15]; //学号char name[20]; //姓名int age; //年龄float math; //数学float english; //英语float physics; //物理struct studentRecord * next;
}SR;struct
{SR record; //学生纪录float total; //总成绩
}stu[10000],temp;void addlist(SR* head,SR* newNode){SR* cur = head;while(cur->next!=NULL){cur=cur->next;}cur->next = newNode;}
void Byorderaddlist(SR* head,SR * newBoy){//找到插入节点的前一个节点 SR* cur = head;bool flag = false;while(true){if(cur->next==NULL){printf("链表为空,调用无序插入\n");addlist(head,newBoy); break;}if (strcmp(cur->next->stuNo,newBoy->stuNo)>0){flag=true;break;}cur=cur->next;}if(flag){newBoy->next = cur->next;cur->next=newBoy;}else{printf("没有找到插入位置,或该位置以存在\n"); }}
void update(SR* head,SR* newBoy){if(head->next==NULL){return;}SR* cur = head->next;bool flag=false;while(cur!=NULL){if(!strcmp(newBoy->stuNo,cur->stuNo)){flag=true;break;}cur=cur->next;}if(flag){newBoy->next = cur->next;cur=newBoy;printf("修改完毕\n"); }else{printf("没有找到\n");}
}void dellist(SR* head,char stuNo[]){//删除指定节点 if(head->next==NULL){printf("链表为空无法再删除\n");return;}bool flag = false;SR* cur = head;while(cur->next!=NULL){if(!strcmp(cur->next->stuNo,stuNo)){flag=true;break;} cur=cur->next;}if(flag){SR* temp=cur->next;cur->next = cur->next->next;free(temp);}else{printf("没有找到要删除的结点\n"); }}void ByStuNoSelectSingleNode(SR* head,char stuNo[]){if(head->next==NULL){printf("链表为空\n"); return;}SR* cur=head->next;while(cur!=NULL){if(!strcmp(cur->stuNo,stuNo)){printf("%s\t%s\t%d\t%5.1f\t%5.1f\t%5.1f\n",cur->stuNo,cur->name,cur->age,cur->math,cur->english,cur->physics);return;}cur= cur->next;}printf("没找到\n");
}
void ByAgeSelectSingleNode(SR* head,int age){if(head->next==NULL){return;}SR* cur=head->next;while(cur!=NULL){if(cur->age==age){printf("%s\t%s\t%d\t%5.1f\t%5.1f\t%5.1f\n",cur->stuNo,cur->name,cur->age,cur->math,cur->english,cur->physics);}cur= cur->next;}printf("没找到\n");
}
void Showlist(SR* head){if(head->next==NULL){printf("链表为空\n");return;}SR* cur =head->next;while(true){if(cur==NULL){break;}printf("%s\t%s\t%d\t%5.1f\t%5.1f\t%5.1f\n",cur->stuNo,cur->name,cur->age,cur->math,cur->english,cur->physics);cur=cur->next; }}void WriteFile(SR* head){//打开文件,同时写入 char c;char filename[20];SR* ptem = head->next;//ptem为辅助变量printf("请输入班级\n");//一个班级一个文件 scanf("%s",filename);FILE * fp = fopen(filename,"a"); while(ptem!=NULL){fprintf(fp,"%s ",ptem->stuNo);fprintf(fp,"%s ",ptem->name);fprintf(fp,"%d ",ptem->age);fprintf(fp,"%5.1f ",ptem->math);fprintf(fp,"%5.1f ",ptem->english);fprintf(fp,"%5.1f\n",ptem->physics);ptem=ptem->next;}printf("保存完毕\n");fclose(fp);fp=NULL;
} void AS(){//成绩统计模块char filename[20];scanf("%s",filename);FILE* fp = NULL;if ((fp = fopen(filename, "r")) == NULL) {printf("can not open file\n");}for (int i = 0; i < 10000; i++) { fscanf(fp, "%s %s %d %f %f %f",stu[i].record.stuNo, stu[i].record.name, &stu[i].record.age, &stu[i].record.math, &stu[i].record.english, &stu[i].record.physics);stu[i].total = stu[i].record.math + stu[i].record.english + stu[i].record.physics;//求和 if(stu[i].record.age==0&&stu[i].record.math==0&&stu[i].record.english==0&&stu[i].record.physics==0||fp==NULL){break;}printf("%5.1f\n",stu[i].total);}fclose(fp);fp = NULL;
} void SSV()
{
char filename[20];scanf("%s",filename);FILE* fp = NULL;if ((fp = fopen("ouhou.txt", "r")) == NULL) {printf("can not open file\n");}int count = 0;for (int i = 0; i < 10000; i++) {fscanf(fp, "%s %s %d %f %f %f",&stu[i].record.stuNo, &stu[i].record.name, &stu[i].record.age, &stu[i].record.math, &stu[i].record.english, &stu[i].record.physics);if(stu[i].record.age==0&&stu[i].record.math==0&&stu[i].record.english==0&&stu[i].record.physics==0){break;}count++;stu[i].total = stu[i].record.math + stu[i].record.english + stu[i].record.physics;//求和 }fclose(fp);//冒泡排序优化版 bool flag = false;for(int j = 0;jstu[k+1].total){flag = true;temp = stu[k];stu[k] = stu[k+1];stu[k+1]=temp;}}if(flag){flag = false;}else{break;}} for(int l = 0;lnext = NULL;if(head==NULL){return 0;} int num;//添加学生的个数 bool loap = true;while(loap){switch(Menu()){case 1:printf("-------学生信息无序录入-------\n");printf("请输入要添加学生的个数\n");scanf("%d",&num);for(int i = 0;istuNo,newNode->name,&newNode->age,&newNode->math,&newNode->english,&newNode->physics);newNode->next = NULL;addlist(head,newNode);}printf("输入完毕\n");break;case 2:printf("-------学生信息有序录入-------\n");printf("请输入要添加学生的个数\n");scanf("%d",&num);for(int i = 0;istuNo,newNode->name,&newNode->age,&newNode->math,&newNode->english,&newNode->physics);newNode->next = NULL;Byorderaddlist(head,newNode);}printf("输入完毕\n");break;case 3:{printf("-------学生信息修改-------\n");SR* newNode = (SR*)malloc(sizeof(SR));printf("学号\t姓名\t年龄\t数学\t英语\t物理\n");scanf("%s %s %d %f %f %f",newNode->stuNo,newNode->name,&newNode->age,&newNode->math,&newNode->english,&newNode->physics);newNode->next = NULL;update(head,newNode);break;}case 4:printf("-------删除学生信息--------\n");printf("请输入要删除的学号\n");char numstu[20];scanf("%s",numstu); dellist(head,numstu);break;case 5:printf("-------根据学号查找---------\n");printf("请输入要查找的学号\n");char numstu1[20];scanf("%s",numstu1);ByStuNoSelectSingleNode(head,numstu1);break;case 6:printf("-------根据年龄查找---------\n");printf("请输入要查找的年龄\n");char age1;scanf("%d",&age1);ByAgeSelectSingleNode(head,age1);break;case 7:printf("----------显示列表----------\n");Showlist(head); break;case 8:printf("----------保存链表----------\n");WriteFile(head);break;case 9:printf("----------成绩统计----------\n");AS();break; case 10:printf("----------成绩查看----------\n");SSV();break; case 11: loap = false;break;default:printf("输入错误请重新输入\n"); }}}
本项目还可扩展,数据到达一定量可以将单链表变为二叉树,加入二叉树排序与搜索,进行数据结构的优化,还可加入快速,归并等排序,
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
