前言

学生成绩管理系统可以说是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. flask中的重定向,渲染,反转视图函数

    在学习flask中,重定向,渲染,反转老是不怎么明白,今天明白了其中的点了,来给大家分享下 rend_templete()这个函数就是一个渲染的作用,渲染html的东西. url_for是反转视图函数 ...

  2. Android夜神模拟器

    夜神安卓模拟器 NOX,是一个可以让手机应用程序运行在电脑上的软件,也是电脑玩手游的新一代神器, 与传统安卓模拟器相比,基于基于Android5.1.1,兼容X86/AMD,在性能.稳定性.兼容性等方 ...

  3. SQL Server 批量插入数据方案 SqlBulkCopy 的简单封装,让批量插入更方便

    一.Sql Server插入方案介绍 关于 SqlServer 批量插入的方式,有三种比较常用的插入方式,Insert.BatchInsert.SqlBulkCopy,下面我们对比以下三种方案的速度 ...

  4. Hello!OA!Hello!工作流!寻找OA和工作流的旅途记录

    最近新到了一家公司,这家公司做的人力资源管理,需要一个OA系统,所以就让我做一个选型,经过我2周时间的筛选,试用,沟通,测试,最终确定了几款,这个艰辛的路程,在这里记录一下~ 寻找OA的路程----- ...

  5. js实现跳转的几种方式

    1. window.open("url"); 2.用自定义函数 <script> function openWin(tag,obj) { obj.target=&quo ...

  6. js动态加载js文件(js异步加载之性能优化篇)

    1.[基本优化] 将所有需要的<script>标签都放在</body>之前,确保脚本执行之前完成页面渲染而不会造成页面堵塞问题,这个大家都懂. 2.[合并JS代码,尽可能少的使 ...

  7. 介质访问控制子层-Medium Access Control Sublayer:多路访问协议、以太网、无线局域网

    第四章 介质访问控制子层-Medium Access Control Sub-layer 4.1介质访问控制子层概述 MAC子层不属于之前提到的OSI或TCP/IP架构的任何一层,这也是为什么这一层被 ...

  8. STL——容器(Set & multiset)的默认构造 & 带参构造 & 对象的拷贝构造与赋值

    1. 默认构造 set<int> setInt;              //一个存放int的set容器. set<float> setFloat;          //一 ...

  9. Python测试框架unittest

    Python测试框架unittest 一.unittest框架 (1)unittest特点 1.python自带的单元测试框架,不需要安装 2.用例执行互不干扰 3.提供不同范围的setUp和tear ...

  10. 前端面试题CSS-div宽度设置为100%,设置属性margin-left和margin-right时出现的问题

    前端面试题CSS-div宽度设置为100%,设置属性margin-left和margin-right时出现的问题 div格式如下 <div class="a"> < ...