一、程序设计目的
通过设计、实现一个学生考勤管理系统,熟悉STL中有关类型及其使用方法,体会和掌握泛型编程的风格,加深对Visual C++集成开发环境的掌握(特别是调试功能),养成良好的编程习惯。
二、系统设计要求../upload/2009/5/26/9aa45349-5eb6-4eca-9210-dab499ffa954.rar
四、程序实现思路
开始是设计程序的界面,了解需要实现的功能模块。
4.1对数据结构的选择
写出的界面,现在需要做的事情其实就是要将所有的菜单功能进行实现。可以考虑将用户输入每个学生的记录用一个结构体里面,即:
struct Student_info {
std::string
date; //缺课日期
std::string
class_num; //第几节课
std::string
course_name; //课程名称
std::string
stu_name; //学生姓名
std::string non_attendance_type; // 缺课类型
};
最后所有的学生记录都保存到一个vector里面,然后根据需要再将里面需要查找的元素进行查找,相应的排序可能就是将他们尽可能压进关联式容器map,有的部分就压入set里面,这些都是根据模块的功能来选定的。可以这么说,选择好合理的数据结构查找与排序就可以一劳永逸了。这点在后面部分会有详细的说明。
4.2对功能的实现
4.2.1录入学生的缺课记录
首先提示用户按照正确的格式进行学生缺课记录的录入,这个步骤比较简单,只需要不断地将记录的每个数据项存入结构体对应的成员中。
4.2.2修改某个学生的缺课记录
首先必须查找到你所需要修改的那位的学生全部缺课记录。这个模块不需要定义新的结构体。
在修改前当然要检查记录是否为空了,不为空的话,可以设置下面这五个菜单供用户选择:
"1、缺课日期2、第几节课3、课程名称
4、学生姓名5、缺课类型6、退出修改程序并返回系统主菜单
修改很简单,仅需要对该学生的某个部分进行替换即可。采用switch语句很快就解决。J最后实现对所选记录的修改,完成后更新原有的学生记录。
4.2.3查询某个学生的缺课情况
查询某个学生的缺课情况,这个模块是在以下这个函数中实现的:
find_student_absent(vector<Student_info>&
students, string& name)
其中name为用户本人输入的学生姓名,这样可以很快在vector里面找到该学生的所有的记录。为了达到查询结果按照日期升序排序,同一天内按照所缺课程的时间升序排序的目的,那就需要选择一个数据结构need来保存查找得到的该学生的所有缺课记录,即:
map<string, map<string,
vector<string> > > need
这个数据结构看起来有点复杂,其实非常好用。第一个索引值string 类型保存学生的缺课的日期,第二个map的键值则为该学生当天在第几节课缺课,而vector用来保存该学生其余信息,那么得到的need保存的记录已经满足了查询结果按照日期升序排序,同一天内按照所缺课程的时间升序排序的要求,只需要按格式输出这些记录即可。
4.2.4统计旷课学生姓名及旷课节数和有学生旷课的课程及旷课人次
这两个模块之所以放在一起讨论,是由于它们其实功能都是大同小异的。可以考虑用泛型编程来解决。不过我在源程序中并没有这么做,而是写成两个函数模块。很大原因是我写的泛型函数编译不通过,不过既然功能相当,就免了。
这个两个模块根据课程名称来找出所有与“旷课”这个字符串有关的记录先暂存到一个vector。考虑到vector远远不能满足客户的要求,那么可以考虑新建一个数据结构来保存这些记录,同时满足要求,即:
map<int, set<string>
> need; //将统计出来的结果保存属于这段时间的学生旷课记录
其中set保存的是旷课学生姓名(有学生旷课的课程),map的键值为学生旷课节数(旷课人次)。
最后会发现一个小问题,输出的结果并不是用户需要的结果先按旷课节数(旷课人次)降序排序,旷课节数相同的学生按姓名(有学生旷课的课程)升序排序,解决的办法很简单,只需要再输出的时候定义一个迭代器即可解决,即:
map<int, set<string>
>::const_reverse_iterator mapset_it = need.rbegin();
该功能得以解决。
4.2.5退出系统
在退出系统时,会出现如下友好界面:
*****************************
* 您选择的是退出本系统, *
* 谢谢使用,欢迎下次光临!*
*****************************
这样可以大大提高客户对我的软件的评价。^_^
五、设计说明文档
5.1 用户使用手册:
5.1.1为了示范:首先给出测试数据如下:
2008-04-29 3-4 汇编语言程序设计 张三 迟到 2008-04-27 7-8 C++程序设计实验 张三 旷课 2008-04-26 3-4 C++程序设计 李四 2008-04-25 3-4 计算机组成原理 李四 2008-04-27 5-6 汇编语言程序设计 张三 迟到 2008-04-29 3-4 C++程序设计实验 张三 旷课 2008-04-25 3-4 C++程序设计 李四 2008-04-25 3-4 C++程序设计 王五 2008-04-26 3-4 计算机组成原理 李四 |
5.1.2 使用步骤说明
用户进入系统时,会出现如下友好界面:
录入学生缺课记录以后,以Ctrl+z结束录入,将出现下面可爱的菜单选项:
接着根据自己的需要选择菜单比如我要修改“2008-04-27 7-8 C++程序设计实验 张三 旷课” 这条记录,为“2008-04-27 3-4 C++程序设计实验 张三旷课”那么可以按照下面的提示以及程序的交互信息操作得到结果:
修改后,系统自动推出到主功能菜单选项处,你可以根据自己的需要进行相应的操作。
又例如我想查找2008-04-26 到2008-04-29这段时间内C++程序设计这门课程旷课学生姓名及旷课节数(假设每次课为一节),可以得到下面的结果:
得到所要求的结果,其中由结果可以看出结果先按旷课节数降序排序,旷课节数相同的学生按姓名升序排序
5.2下面是软件下载说明书:
╭════════════════╮
║ ║
╭═══┤ 学生考勤系统 ├══════╮
║ ║ ║
║
║ ╰════════════════╯
║
║
此软件版权归原作者所有。 ║
║ 具体操作纯属您自己的选择, ║
║ 此文件对您造成的任何损失, ║
║ 本人不承担任何责任。请支持正版! ║
║网址:http://space.ednchina.com/userinfo. ║
║ aspx?ID=39BA1C182A0D985A ║
║
║
║ ╭───────────────────-──╮ ║
╰══┤ 欢迎您的使用 J
├══╯
╰──────────────────────╯
六、课程设计心得
本次课程设计主要使用到了STL里面的容器和一些比较基本的算法,总体上感觉比之前做过的实验综合性比较强。在这里我主要总结一下我设计这个学生考勤管理系统的心得和在编译程序的过程中遇到的问题以及解决的办法。
为了使得程序的编写更加有条理,阅读更加明了,在写每个模块的时候都将自己的思路写在每个函数的第一行,告诉自己(读者)我这个函数将要做的是什么事情。这是一个很好的编程规范,值得继续发扬J。
在设计好思路以后就是测试数据的设计,不过本次实验的测试数据比较死板,没什么好变动的。
由于时间把握不好,这个系统是在三天空余时间写出来的,难免有点仓促,任然有许多需要改进的方向,但基本的功能已经达到了。
下面实对调试过程中遇到的一些小收获:
①编译时发现这样的小错误:
1>d:\my documents\visual
studio 2005\projects\course1\course1\main.cpp(69) : error C2360: initialization
of 'name' is skipped by 'case' label
最后得到的解决答案实:原来在case 语句中,是不允许声明变量的。
②初次使用const_reverse_iterator的总结:
运行的时候出现“map set iterator not incrementable”这样的运行终止错误
问题的结局:经过检验查出是const_reverse_iterator
原因是:map<int, set<string>
>::const_reverse_iterator mapset_it = need.rbegin();
for(;
mapset_it != need.rend(); mapset_it--)
mapset_it的操作不能是mapset_it--操作,而应该是mapset_it++
七、关键程序代码
说明:由于篇幅有限,部分程序将使用伪代码的形式给出,比如一些繁冗的初始化,还有一些屏幕打印的部分都会由伪代码代替。
(该部分请看附件)
用户377235 2012-3-5 11:52
挺好哦 就是有些东西看不见哦
用户201423 2009-12-8 17:07
用户201423 2009-12-8 16:56
用户240594 2009-12-4 01:18
用户242121 2009-11-1 17:16
用户398740 2009-6-11 16:50
用户398740 2009-6-11 16:27