前言

学生成绩管理系统可以说是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程序设计大作业——学生成绩管理系统的更多相关文章

  1. 【C】C语言大作业——学生学籍管理系统

    文章目录 学生管理系统 界面 主界面 登陆界面 注册界面 管理界面 学生界面 退出界面 链接 注意 学生管理系统 学C语言时写的一个大作业,弄了一个带图形界面的,使用的是VS配合EasyX图形库进行实 ...

  2. C语言大作业---学生信息管理系统

    xxxx信息管理系统 简介 因为大作业规定的踩分项就那么多,为了不浪费时间 + 得分,就写成这样.现在看看,命名不规范,书写风格糟糕,全塞在一个源代码中······ 不过,应付大作业是没问题的 实验报 ...

  3. 【学生成绩管理系统】 大二c语言作业

    几年前写的了,只能在命令行窗口运行,虽然比较挫,还是有一定参考价值... #include <cstdio> #include <conio.h> #include <i ...

  4. 第一次写C语言小程序,可以初步理解学生成绩管理系统的概念

    1 成绩管理系统概述 1.1  管理信息系统的概念  管理信息系统(Management Information Systems,简称MIS),是一个不断发展的新型学科,MIS的定义随着科技的进步也在 ...

  5. Java项目:学生成绩管理系统(一)

    学生成绩管理系统(一) 项目名称:学生成绩管理系统 项目需求分析(Need 需求): (1)该系统的用户分为教师和学生.教师的功能有:管理某一学生或课程的信息以及成绩,包括增.删.查.报表打印等:学生 ...

  6. 使用C++名单在文档处理和学生成绩管理系统相结合

    对于学生成绩管理系统,我并不陌生,几乎学习C人的语言.做项目会想到学生成绩管理系统,我也不例外.在研究中的一段时间C语言之后,还用C语言到学生管理系统,然后做几个链接.计数,这个系统是以前的系统上的改 ...

  7. 基于MFC的学生成绩管理系统的设计与实现

    1.技术介绍MFC是微软基础类库的简称,是微软公司实现的一个C++类库,主要封装了大部分的WINDOWS API函数,并且包含一个应用程序框架,以减少应用程序开发人员工作量.VC++是微软公司开发的C ...

  8. java学生成绩管理系统

                                                       信1805-1 20183590 田庆辉             石家庄铁道大学 2019 年秋季 ...

  9. Java项目:学生成绩管理系统(二)

    学生成绩管理系统(二):项目介绍 一.设计要求: 1.1 简单的图形界面登录功能. 1.2 对数据库的的信息的查询功能. 1.3 对数据库的的信息的修改功能. 1.4 对数据库的的信息的删除功能. 1 ...

随机推荐

  1. 再也不怕 JavaScript 报错了,怎么看怎么处理都在这

    在开发中,有时,我们花了几个小时写的 JS 代码,在游览器调试一看,控制台一堆红,瞬间一万头草泥马奔腾而来.至此,本文主要记录 JS 常见的一些报错类型,以及常见的报错信息,分析其报错原因,并给予处理 ...

  2. Nginx 转发时的一个坑,运维居然让我背锅!!

    最近遇到一个 Nginx 转发的坑,一个请求转发到 Tomcat 时发现有几个 http header 始终获取不到,导致线上出现 bug,运维说不是他的问题,这个锅我背了. 新增的几个 header ...

  3. centos7.5以上poenssl和openssh升级

    2020年12月09日,360CERT监测发现  openssl  发布了  openssl 拒绝服务漏洞  的风险通告,该漏洞编号为  CVE-2020-1971  ,漏洞等级:高危 ,漏洞评分:7 ...

  4. springboot配置ssl证书

    springboot默认使用的是tomcat: 1.先到阿里云上注册一个证书,绑定域名:后面可以在管理中下载证书,下载tomcat对应的证书(一个*.pfx文件和*.txt文件) 2.将pfx文件拷贝 ...

  5. Windows10自带截屏快捷键

    Windows10自带截屏快捷键使用方法大全我们知道,QQ和微信以及第三方浏览器等软件都支持截图功能,但是这个都是基于软件的一个功能,如果我们不打开这些软件的话,就不能实现截图功能,但其实window ...

  6. 漫谈 HTTP 性能优化

    本文主要是侧重于 HTTP 的优化,对于 HTTPS 后续文章会讲. 既然要做性能优化,那么,我们就需要知道:什么是性能?它都有哪些指标,又应该如何度量,进而采取哪些手段去优化? "性能&q ...

  7. Java中CAS原理分析(volatile和synchronized浅析)

    CAS是什么? CAS英文解释是比较和交换,是cpu底层的源语,是解决共享变量原子性实现方案,它定义了三个变量,内存地址值对应V,期待值E和要修改的值U,如下图所示,这些变量都是在高速缓存中的,如果两 ...

  8. 六、TestNG传递参数1

    TestNG可以通过testng.xml和Data Providers向测试方法传递参数 利用testNG.xml传递参数 1-创建一个TestNG测试类 其中 parameters = {" ...

  9. AOP基本概念

    连接点joinpoint(类中所有方法) 切入点pointcut(缺少共性代码的方法) 通知advice(被抽取的共性功能的代码逻辑,通知有位置区分,也就是从切入点方法中被抽取代码的前面还是后面抽象出 ...

  10. Greenplum 性能优化之路 --(二)存储格式

    一.存储格式介绍 Greenplum(以下简称 GP)有2种存储格式,Heap 表和 AO 表(AORO 表,AOCO 表). Heap 表:这种存储格式是从 PostgreSQL 继承而来的,目前是 ...