从零开始的C程序设计大作业——学生成绩管理系统
前言
学生成绩管理系统可以说是C语言程序设计的结课的必备大作业了。花了些时间,费了些头发肝了下,完成了两个系统,一个是控制台版本的,另一个用easyx图形库进行了优化。
先放出完成后的演示图片占个坑。具体的实现过程,等我再梳理下,再慢慢更新整理到论坛上来。
演示DEMO
基础控制台版本
控制台版本开发过程整理
开发环境
系统: win10
IDE: Dev Cpp
前置知识
需要掌握基础的C语言知识
- 顺序结构
- 分支结构
- 循环结构
- 数组、字符串
- 函数
- 结构体、指针
- 链表
- 文件操作
功能分析
工欲善其事必先利其器,先分析好整体功能和大体的布局再慢慢动手进行代码的实现。
基础设想是,先显示主菜单,通过输入数字选择对应的功能,包括有增加学生信息,删除学生信息,修改学生信息,查询学生信息以及退出程序功能。
主菜单界面实现
使用输出语句来实现界面。计划使用数字键来代表各自的功能。
//主菜单界面
void welcome(){
printf("************************\n");
printf("** 学生成绩管理系统 **\n");
printf("** 作者:咸鱼君 **\n");
printf("** **\n");
printf("** 增加学生信息 ---1 **\n");
printf("** 删除学生信息 ---2 **\n");
printf("** 修改学生信息 ---3 **\n");
printf("** 查询学生信息 ---4 **\n");
printf("** 输出学生信息 ---5 **\n");
printf("** 退出管理系统 ---0 **\n");
printf("请输入对应的功能键(数字): ");
}
功能框架搭建
先处理好整个功能框架,通过输入数字,进行分支判断,不同的数字代表不同的功能。先将要实现的功能做个简易的版本出来,之后再慢慢填充细节。
想的是执行完某些功能后还能继续进行操作,所以将程序放入循环中,并在操作执行完成后,询问继续操作,再根据选择进行处理。
int main(){
int choice=0;
while(true){
welcome();
scanf("%d",&choice);
switch(choice){
case 1://增加学生信息
addStuInfo();
break;
case 2://删除学生信息
deleteStuInfo();
break;
case 3://修改学生信息
fixStuInfo();
break;
case 4://查询学生信息
searchStuInfo();
break;
case 5://输出学生信息
printStuInfo();
break;
case 0://退出程序
goodBye();
break;
}
printf("是否需要继续操作?(yes:1 / no:0 ):");
scanf("%d",&choice);
if(choice==0){
break;
}
}
return 0;
}
数据结构定义
围绕学生信息进行处理,那么思考学生具有哪些信息。包含,学号,姓名,性别,语文,数学,英语成绩,还有个总分。将对应属性集合在一块,采用结构体方式进行数据操作。并使用链表的方式将数据进行串联。
typedef struct Node{
int id;//学号
char name[30];//姓名
char sex[10];//性别
int ch;//语文
int ma;//数学
int en;//英语
int sum;//总分
struct Node *next;//指向下一个结点
}node;
文件数据的读取
这此程序的数据都要以文件的形式进行信息的保存,如果想要在屏幕上输出数据,那么得先读取文件中的信息才行。
C语言中文件读取操作要使用文件指针和相关函数,格式如下。
FILE *fpr=fopen("文件名","操作方式");
fscanf(fpr,"%d",&intValue);
文件名需要加上后缀名,操作方式因为是要从文件中读取信息,所以写r。如果是进行信息的写入则是w。
之后需要将读取的信息以链表的方式组织起来,打算采用尾插法的方式插入数据。
// 尾插法
t->next=s;//链表尾指针 的后一个结点指向新结点
t=s;//更新尾结点
t->next=NULL;//链表尾指针 的后一个结点指向NULL
读取函数
// 文件输入
int readFile(Node *L){
FILE *fpr=fopen("studentInfo.txt","r");
node *t=L;
node st;
node *s;
if(fpr==NULL){
return 0;
}else{
//fscanf()
while(fscanf(fpr,"%d %s %s %d %d %d %d",&st.id,st.name,st.sex,&st.ch,&st.ma,&st.en,&st.sum)!=EOF){
s=(node *)malloc(sizeof(node));
*s=st;
// 尾插法
t->next=s;//链表尾指针 的后一个结点指向新结点
t=s;//更新尾结点
t->next=NULL;//链表尾指针 的后一个结点指向NULL
}
}
fclose(fpr);//关闭文件指针
return 1;
}
输出所有学生信息
接下来完成所有学生信息的输出。此处需要考察链表的遍历。
void printStuInfo(node *L){
system("cls");
node *p=L->next;
printf("________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|语文\t|数学\t|英语\t|总分\t|\n");
printf("________________________________________________________\n");
if(p!=NULL){
while(p!=NULL){
printf("%d|%s\t|%s\t|%d\t|%d\t|%d\t|%d\t|\n",p->id,p->name,p->sex,p->ch,p->ma,p->en,p->sum);
printf("________________________________________________________\n");
p=p->next;
}
}
}
增加学生信息
接下来是增加学生的信息,此处采用头插法将链表结点进行插入。将学生信息的增加分成了两部分,一部分是界面的打印,一部分是底层数据的处理。
界面实现:
//增加学生信息
void printAddStuInfo(){
//
system("cls");
node st;
printf("请输入新增学生相关信息\n");
printf("学号:");
scanf("%d",&st.id);
printf("姓名:");
scanf("%s",st.name);
printf("性别:");
scanf("%s",st.sex);
printf("语文:");
scanf("%d",&st.ch);
printf("数学:");
scanf("%d",&st.ma);
printf("英语:");
scanf("%d",&st.en);
st.sum=st.ch+st.ma+st.en;
insertStuInfo(&List,st);
}
功能实现:
void insertStuInfo(node *L,node e){
//头插法
node *h=L;
node *s=(node *)malloc(sizeof(node));
*s=e;
s->next=h->next;
h->next=s;
}
文件数据的写入
这部分和文件的读取部分相似,思路是将整个链表内容存储到文件中。
使用fprintf()将文件信息进行存储。
//保存文件
int saveFile(node *L){
FILE *fpw=fopen("studentInfo.txt","w");
if(fpw==NULL) return 0;
node *p=L->next;
while(p!=NULL){
fprintf(fpw,"%d %s %s %d %d %d %d\n",p->id,p->name,p->sex,p->ch,p->ma,p->en,p->sum);
p=p->next;
}
fclose(fpw);//关闭文件指针
return 1;
}
再在学生信息的增加过程中添加文件数据的保存操作。
void insertStuInfo(node *L,node e){
//头插法
node *h=L;
node *s=(node *)malloc(sizeof(node));
*s=e;
s->next=h->next;
h->next=s;
//保存文件
saveFile(L);
}
学生信息查询
接下来是实现学生信息查询功能,计划也是页面输出部分与逻辑实现部分进行分离。打算,可以通过学号与姓名两个关键值进行信息的查找。因为是链表结构,为了方便之后的操作,逻辑函数会返回查找到的学生信息的前一个结点位置,这样的话也能在删除学生信息与修改学生信息中进行函数的复用了。
界面实现:
//查询学生信息
void printSearchStuInfo(node *L){
system("cls");
int choice=0;
int id;
char name[50];
node *st;
printf("按学号查询----- 1\n");
printf("按姓名查询----- 2\n");
printf("请输入查询方式:");
scanf("%d",&choice);
if(choice == 1){
printf("请输入要查询的学号:");
scanf("%d",&id);
st=searchStuInfoById(id,L);
if(st==NULL){
printf("查无此人!\n");
}else{
st=st->next;
printf("________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|语文\t|数学\t|英语\t|总分\t|\n");
printf("________________________________________________________\n");
printf("%d|%s\t|%s\t|%d\t|%d\t|%d\t|%d\t|\n",st->id,st->name,st->sex,st->ch,st->ma,st->en,st->sum);
printf("________________________________________________________\n");
}
}else if(choice ==2){
printf("请输入要查询的姓名:");
scanf("%s",name);
st=searchStuInfoByName(name,L);
if(st==NULL){
printf("查无此人!\n");
}else{
st=st->next;
printf("________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|语文\t|数学\t|英语\t|总分\t|\n");
printf("________________________________________________________\n");
printf("%d|%s\t|%s\t|%d\t|%d\t|%d\t|%d\t|\n",st->id,st->name,st->sex,st->ch,st->ma,st->en,st->sum);
printf("________________________________________________________\n");
}
}
}
逻辑实现:
思路是遍历整个链表,逐一对关键信息进行比较。
按学号进行查找,找不到返回NULL,找到了返回前一个结点位置
//按学号进行查找
node * searchStuInfoById(int id,node *L){
node *p=L;
while(p->next!=NULL){
if(p->next->id==id){
return p;
}
p=p->next;
}
return NULL;
}
按姓名进行查找,找不到返回NULL,找到了返回前一个结点位置
//按姓名进行查找
node * searchStuInfoByName(char name[],node *L){
node *p=L;
while(p->next!=NULL){
if(strcmp(name,p->next->name)==0){
return p;
}
p=p->next;
}
return NULL;
}
学生信息修改
依旧是分成两部分,先输出界面,过程逻辑的话就沿用学生信息查询的部分。实现逻辑是这样的:先查到要查询的学生信息,在对信息修改,改完了再保存到文件中。
页面和实现部分:
//修改学生信息
void printFixStuInfo(node *L){
system("cls");
int id;
int choice=-1;
printf("请输入要查找的学生学号");
scanf("%d",&id);
node *st=searchStuInfoById(id,L);
if(st==NULL){
printf("查无此人!");
return;
}
st=st->next;
while(1){
system("cls");
printf("________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|语文\t|数学\t|英语\t|总分\t|\n");
printf("________________________________________________________\n");
printf("%d|%s\t|%s\t|%d\t|%d\t|%d\t|%d\t|\n",st->id,st->name,st->sex,st->ch,st->ma,st->en,st->sum);
printf("________________________________________________________\n");
printf("修改姓名---- 1\n");
printf("修改性别---- 2\n");
printf("修改语文---- 3\n");
printf("修改数学---- 4\n");
printf("修改英语---- 5\n");
printf("请输入要修改的信息: ");
scanf("%d",&choice);
switch(choice){
case 1:
printf("请输入姓名:");
scanf("%s",st->name);
break;
case 2:
printf("请输入性别:");
scanf("%s",st->sex);
break;
case 3:
printf("请输入语文:");
scanf("%d",&st->ch);
break;
case 4:
printf("请输入数学:");
scanf("%d",&st->ma);
break;
case 5:
printf("请输入英语:");
scanf("%d",&st->en);
break;
}
st->sum=st->ch+st->ma+st->en;
printf("是否继续修改学生信息?(y-1 / n-0)\n");
scanf("%d",&choice);
if(choice == 0){
break;
}
}
printf("________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|语文\t|数学\t|英语\t|总分\t|\n");
printf("________________________________________________________\n");
printf("%d|%s\t|%s\t|%d\t|%d\t|%d\t|%d\t|\n",st->id,st->name,st->sex,st->ch,st->ma,st->en,st->sum);
printf("________________________________________________________\n");
//保存文件信息
saveFile(L);
}
学生信息删除
接下来实现学生信息删除部分。页面部分输出提示,之后输入学号查询要删除的学生信息。利用之前实现的查询信息的函数得到结点位置,之后再根据位置删除对应的结点,再将修改后的信息保存至文件中去。
页面部分
//删除学生信息
void printDeleteStuInfo(node *L){
system("cls");
int id;
node *p;
printf("请输入要查找的学生学号");
scanf("%d",&id);
node *st=searchStuInfoById(id,L);
p=st;
if(st==NULL){
printf("查无此人!");
return;
}
st=st->next;
printf("________________________________________________________\n");
printf("|学号\t|姓名\t|性别\t|语文\t|数学\t|英语\t|总分\t|\n");
printf("________________________________________________________\n");
printf("%d|%s\t|%s\t|%d\t|%d\t|%d\t|%d\t|\n",st->id,st->name,st->sex,st->ch,st->ma,st->en,st->sum);
printf("________________________________________________________\n");
deleteStuInfo(p);
saveFile(L);
}
结点删除部分
//删除学生信息
void deleteStuInfo(node *pr){
node *s=pr->next;
pr->next=s->next;
s->next=NULL;
free(s);//释放结点空间
}
结束界面
到此为止,这个小系统的基础功能都已经完成了。接下来把结束界面处理下。
//退出程序
void goodBye(){
system("cls");
printf("欢迎下次使用~\n");
exit(0);//结束程序
}
学生成绩管理系统V1.0版本到此也就完结了。之后也可以在此基础上进行其他功能的开发,比如,程序排序,最高分,平均分等等的处理。大体都是围绕链表的遍历,插入和删除操作来执行的。再结合自己对界面的设计即可。
从零开始的C程序设计大作业——学生成绩管理系统的更多相关文章
- 【C】C语言大作业——学生学籍管理系统
文章目录 学生管理系统 界面 主界面 登陆界面 注册界面 管理界面 学生界面 退出界面 链接 注意 学生管理系统 学C语言时写的一个大作业,弄了一个带图形界面的,使用的是VS配合EasyX图形库进行实 ...
- C语言大作业---学生信息管理系统
xxxx信息管理系统 简介 因为大作业规定的踩分项就那么多,为了不浪费时间 + 得分,就写成这样.现在看看,命名不规范,书写风格糟糕,全塞在一个源代码中······ 不过,应付大作业是没问题的 实验报 ...
- 【学生成绩管理系统】 大二c语言作业
几年前写的了,只能在命令行窗口运行,虽然比较挫,还是有一定参考价值... #include <cstdio> #include <conio.h> #include <i ...
- 第一次写C语言小程序,可以初步理解学生成绩管理系统的概念
1 成绩管理系统概述 1.1 管理信息系统的概念 管理信息系统(Management Information Systems,简称MIS),是一个不断发展的新型学科,MIS的定义随着科技的进步也在 ...
- Java项目:学生成绩管理系统(一)
学生成绩管理系统(一) 项目名称:学生成绩管理系统 项目需求分析(Need 需求): (1)该系统的用户分为教师和学生.教师的功能有:管理某一学生或课程的信息以及成绩,包括增.删.查.报表打印等:学生 ...
- 使用C++名单在文档处理和学生成绩管理系统相结合
对于学生成绩管理系统,我并不陌生,几乎学习C人的语言.做项目会想到学生成绩管理系统,我也不例外.在研究中的一段时间C语言之后,还用C语言到学生管理系统,然后做几个链接.计数,这个系统是以前的系统上的改 ...
- 基于MFC的学生成绩管理系统的设计与实现
1.技术介绍MFC是微软基础类库的简称,是微软公司实现的一个C++类库,主要封装了大部分的WINDOWS API函数,并且包含一个应用程序框架,以减少应用程序开发人员工作量.VC++是微软公司开发的C ...
- java学生成绩管理系统
信1805-1 20183590 田庆辉 石家庄铁道大学 2019 年秋季 ...
- Java项目:学生成绩管理系统(二)
学生成绩管理系统(二):项目介绍 一.设计要求: 1.1 简单的图形界面登录功能. 1.2 对数据库的的信息的查询功能. 1.3 对数据库的的信息的修改功能. 1.4 对数据库的的信息的删除功能. 1 ...
随机推荐
- VMware 12 与Centos 7建立共享文件夹 && vmware 15 pro过期激活秘钥
1 vmware 15pro评估过期 网上找到的激活秘钥,激活密钥: YG5H2-ANZ0H-M8ERY-TXZZZ-YKRV8(亲试有效)UG5J2-0ME12-M89WY-NPWXX-WQH88U ...
- dm8数据库的安装 for linux
目录 dm8数据库的安装 for linux 1.创建用户 2.修改limit的文件 3.解压文件安装包 4.挂载iso镜像 5.对于安装介质和目录进行权限授予 6.切换用户安装数据库软件 7.dm数 ...
- Newbe.ObjectVisitor 0.4.4 发布,模型验证器上线
Newbe.Claptrap 0.4.4 发布,模型验证器上线. 更新内容 完全基于表达式树的模型验证器 本版本,我们带来了基于表达式树实现的模型验证器.并实现了很多内置的验证方法. 我们罗列了与 F ...
- 通过url传递对象
1.使用 encodeURI() 对对象进行编码 2.在另一个页面使用
- 推荐系统实践 0x0e LS-PLM
在之前介绍的几个模型中,存在这些问题: LR不能捕捉非线性,只能进行一次的回归预测 GBDT+LR虽然能够产生非线性特征组合,但是树模型不适用于超高维稀疏数据 FM利用二阶信息来产生变量之间的相关性, ...
- OpenResty&Canal
OpenResty&Canal OpenResty 提供缓存功能 封装了Nginx,并且提供了Lua扩展,大大提升了Nginx的并发处理能力10k~1000k Nginx限流 1.控制速率 2 ...
- django添加检查用户名和手机号数量接口
1.1 在user/urls.py中添加 urlpatterns = [ path('count/', views.RegCountView.as_view()), # 查询用户名手机号使用量的视图, ...
- MySQL MHA安装配置
1.环境规划 192.168.12.131 node01 192.168.12.132 node02 192.168.12.133 node03 2.环境准备 一主两从GTID,略. 3.配置关键程序 ...
- SpringBoot + Layui +Mybatis-plus实现简单后台管理系统(内置安全过滤器)
1. 简介 layui(谐音:类UI)是一款采用自身模块规范编写的前端UI框架,遵循原生HTML/CSS/JS的书写与组织形式,门槛极低,拿来即用.其外在极简,却又不失饱满的内在,体积轻盈,组件丰 ...
- hive with as 语法
简介 with...as...需要定义一个sql片段,会将这个片段产生的结果集保存在内存中, 后续的sql均可以访问这个结果集和,作用与视图或临时表类似. 语法说明 with...as...必须和其他 ...