前言

学生成绩管理系统可以说是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. 在 GitHub 玩硬件——GitHub 热点速览 Vol.49

    作者:HelloGitHub-小鱼干 本周的 GitHub Trending 可以说是非常之硬核,天才少年稚晖君的 2 个硬件变装项目荣登热点榜,看完将充电宝改装为显示器的视频,搭配 HDMI-PI ...

  3. PC微信[多开+免扫码+防撤回撤回提示+转存语音+自动收款+远程命令]

    PC端微信玩出了新花样,主要技术为Hook技术 有兴趣的小伙伴可以去了解下hook钩子技术 版本介绍: 增加转存语音到MP3(保存你重要的语音数据) 增加表图转存; 增加自动收转账和自动回复; 增加远 ...

  4. python web的一些常见技术面试笔试题

    1. 三次握手四次挥手   tcp建立连接的过程是三次挥手,断开连接是4次挥手. 三次握手:建立连接时 a. 客户端发送syn=1 seq=k给服务器 b. 服务器接收到之后知道有客户端想建立连接, ...

  5. 传输层-Transport Layer(下):UDP与TCP报头解析、TCP滑动窗口、TCP拥塞控制详解

    第六章 传输层-Transport Layer(下) 上一篇文章对传输层的寻址方式.功能.以及流量控制方法做了简短的介绍,这一部分将介绍传输层最重要的两个实例:TCP协议和UDP协议,看一看之前描述的 ...

  6. Java 8 新特性:Lambda、Stream和日期处理

    1. Lambda 简介   Lambda表达式(Lambda Expression)是匿名函数,Lambda表达式基于数学中的λ演算得名,对应于其中的Lambda抽象(Lambda Abstract ...

  7. Java 8 新特性——实践篇

    Java 8 新特性--实践篇 参考 Java8新特性 重要更新:Lambda 表达式和Stream API Lambda 表达式 Lambda 表达式引入之前: 举个场景例子:当我们要对一个班级里的 ...

  8. win10平衡模式、高性能模式和卓越模式三种电池模式的区别

    win10在1803版本后,有了很多隐藏的功能.电池模式中的"卓越模式"就是其中之一. 互相比较一下: 节能模式:顾名思义是最省电的,此模式下会禁用一些系统特效,且CPU运行频率是 ...

  9. learn Docker from scratch (1)

    一.前言 Docker容器一个很有趣的东西,下面链接内容适合docker的入门非常棒! 链接如下: http://www.ruanyifeng.com/blog/2018/02/docker-tuto ...

  10. Kubernetes【K8S】(五):Service

    Service概念 Kubernetes Service定义了一个Pod的逻辑分组,一种可以访问它们的策略.这组Pod能被Service访问到,通常是通过label Selector. Service ...