学生管理系统(详细说明)
- 一. 简要介绍
- 二. 数据集
- 三. 四大模块
-
- 1. 模块一:文件读写
-
- 1.1. csv文件
- 1.2 文件读入
- 1.3 文件写出
- 2.模块二:辅助函数
-
- 2.1 链表释放函数
- 2.2 插入结点函数
- 2.3 链表排序函数
- 3.模块三:基本功能
-
- 3.1 添加
- 3.2 删除
- 3.3 查找
- 3.4 修改
- 4. 模块四:显示信息
-
- 4.1 显示所有学生
- 4.2 显示单个学生
- 4.3 打印班级学生
- 4.4 打印年级学生
- 四.总结
一. 简要介绍
本程序基于链表数据结构实现学生信息的增删改查四大基本功能,同时以.csv
文件作为数据的本地存储方式。本程序共包含四个模块:文件的读写,基本功能实现,信息显示等,辅助模块等。
环境: vscode2021 win10
备注:为避免本文篇幅过长,文中就不再放代码了,可以去下载源代码结合一起看。
百度云:https://pan.baidu.com/s/1TGFXlfqa-Hv3gvReR42AwA?pwd=2234
提取码:2234
github:https://github.com/JWven/C-language-project
- 另外本程序使用GBK2321编码,使用其他编码打开可能显示乱码
附上部分界面图
二. 数据集
数据集包含以下九个标签:名字(name), 在读状态(continue_drop), 学号(student_id), 性别(gender), 年级(grade), 班别(class), 语文成绩(Chinese_marks), 英语成绩(english_marks), 数学成绩(math_marks), 共有6000条数据,包含1-6年级学生。数据量可根据需求缩减。数据来源:基于kaggle中数据进行改造(excel随机生成等)。
三. 四大模块
1. 模块一:文件读写
1.1. csv文件
相关介绍:csv文件(Comma-Separated Values,逗号分隔值),其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样被解读的数据。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。csv文件可以由excel打开并修改。(百度百科)
1.2 文件读入
1.2.1 总体思路:
使用链表存储文件数据( 链表使用 )
因每个数据的大小不一,每次读取一个字段后文件位置不便确定,因此不直接将文件数据读入到链表中,而是每次读入一行,置于字符数组中,再将数组中字符转化为数值并使用循环逐一存入链表结点中。有兴趣可以尝试使用 fread
或其他类似函数直接读取文件。
使用fgets函数读取文件
读入时注意要忽略第一行,因为第一行为数据标签。读入一行数据后将其存放在字符数组中,名字可以直接循环赋值给结点中name
数组,而其他数据由于是字符,需要将其转化为数值,这里使用atoi
,atof
,atol
等函数。有兴趣可以尝试使用其他类似函数。
1.2.2 说明
文件读入部分包括read_file
函数和data_input
函数,前者读入文件并创建链表,后者主要把读入的一行字符型数据转化为数值型数据,并存于结点中
data_temp
数组作用是作为临时数组存储一行数据中的某段数字字符。注意atoi等函数特性,其会将字符数组内所有出现的数字都转化为数值。
我们需要在每次完成字符转换为数值后将temp
数组置空。如果上一次转换完成后没有置空,下一次将数据赋值给data_temp
数组后,若这个数据小于上次的数据,则不足以覆盖上一次的数据,那么此时的数组里不仅包含了这一次的数据,还可能会有上一次数据的残留,这样转化后的数值并非是我们需要的数值。
最后记得关闭文件
1.2.3 缺陷
该函数使用了大量循环结构,使得代码略显冗长,可以尝试改进一下~
1.3 文件写出
相对于文件读入而言,写出较为容易,文件写出部分包含write
函数
主要使用fprintf
函数按行写出数据即可。
2.模块二:辅助函数
2.1 链表释放函数
函数为disposal_LinkList
。方法:从头结点开始逐个free
掉结点即可。至于为什么需要释放,只是出于个人习惯,有人说不释放掉会导致内存泄漏,进程非正常结束的时候,内存就会丢失;有人说进程结束后内存会自动释放,释不释放无关紧要。
2.2 插入结点函数
insert
函数,针对链表的插入结点操作,思路很简单,依据学号进行遍历,有序(升序)插入,不破坏原有学号的排序。这里或许有更先进的搜索算法。
2.3 链表排序函数
sort
函数,以学号为依据对链表进行升序排列,因为修改学生学号后需要进行重新排序。这里使用非最优的冒泡排序法 (或许可以尝试更先进的排序算法)。同时针对结点有不同的交换方式,如直接交换结点和只针对结点的数据域进行交换,这里使用后者。
3.模块三:基本功能
这几个基本功能都是基于链表的操作,对链表不熟悉的话可以复习一下( 链表使用 )
另外程序中scanf
后面一般跟随有getchar
,以丢弃输入后剩下的换行符,防止其在下一次从缓冲区被读入。
3.1 添加
包含add
函数,data_input
函数,insert
函数,与文件读入类似,按规定格式输入一行,即一个学生的信息,然后读入到字符数组中,使用data_input
将字符转换为数值,再使用insert
插入到链表里。
3.2 删除
包含clear
函数,大致是按照学号进行搜索,然后删除链表中结点的操作,较为简单。可以尝试更先进的搜索算法。
3.3 查找
包含seek
函数,在链表中搜索结点,链表的操作。
3.4 修改
change
函数,用户选择需要修改的学生和具体信息,也可以选择全部修改,如果修改了学号就要进行重新排序。使用switch
语句进行选择。
4. 模块四:显示信息
4.1 显示所有学生
print
函数,注意打印信息的同时需要将数据中将0和1转化为具体含义:是/否,男/女等。同时注意格式对齐,这里对两字名字和三字名字进行了区分。最后遍历链表输出即可。
4.2 显示单个学生
print_personael
函数,传入一个结点作为参数,打印数据即可。
4.3 打印班级学生
print_class
函数,遍历链表,当年级和班级均符合时便打印,同样区分两字名字和三字名字。
4.4 打印年级学生
print_grade
函数,基本和print_class
函数相同
最后提供用户接口user
函数和main
主函数。
user
主要使用switch
为用户提供选项,结构较为清晰,具体见源代码。
四.总结
整个程序没啥难点,当初除了处理文件读写时不太熟悉,需要花费点功夫之外,其余函数的实现基本上都是针对链表的操作,可以作为c语言入门之后的练手项目。
另外程序可能含有一些bug,欢迎批评指正,代码也还有很大的优化空间。