计算机科学与技术系
课程设计报告
2010~2011学年第二期
课学学专指
业导
班教生
姓
程 C++程序设计语言
学生考勤管理系统
王兵 ********** 网络工程(2)班 何立新、陈艳平
名 号 级 师
课程设计名称
2011年7月
学生考勤管理系统
目录
一.需求分析 ............................................. 3
1.1 功能需求 ......................................................................................................... 3
1.2 数据需求 ......................................................................................................... 3 1.3 性能需求 ......................................................................................................... 3
二.算法设计 ............................. 错误!未定义书签。
2.1设计思想 .......................................................................................................... 3
2.2功能实现 .......................................................................................................... 7
三.用户手册 ............................................ 7
四. 调试及测试 .......................................... 8
五. 总结 ............................................... 13
六.参考文献 ........................................... 14
附录——源程序 ......................................... 14
2
一.需求分析
开发一个好的软件,进行深入细致的可行性研究是极其必要的,而且还必须做大量的,全面的需求分析,需求分析是软件定义时期的最后一个阶段,它更是开发一个好的软件的基础。它的基本任务是准确地回答“需要此软件的人都需要哪些功能?”这个问题。
需求分析的主要任务是确定系统必须完成哪些工作,也就是对目标系统提出完整的﹑准确的﹑具体的﹑清晰的要求,确定系统必须具有的功能和性能,系统要求的运行环境,以及预测系统发展的前景,并仔细分析系统中的数据,以便完善良好的软件环境。在需求分析阶段系统分析员将仔细研究软件所需要完成的具体功能。 1 功能需求:
1、录入学生的缺勤记录; 2、修改某个学生的缺勤记录; 3、查询某个学生的缺勤情况;
4、统计某段时间内,缺勤学生学号及缺勤次数,按缺勤权值统计学生的负分值,并能进行排序;
5、统计某段时间内,有学生旷课的课程及旷课人次,按旷课人次由多到少排序; 6、系统以菜单方式工作 2 数据需求
本系统主要涉及的数据有学生缺课信息类和有关信息排序类。学生缺课信息包括缺课时间,学生姓名,课程名称,第几节,学生迟到次数,早退次数,请假次数,旷课次数。有关信息排序类包括对课程排序和对姓名排序。 3性能需求
要求系统具有可靠性,速度要快
二、算法设计
1.设计思想
学生考勤系统结构图:
基类的数据成员和成员描述
record String date,cname,sname; int cno,type; 3
void set(); string tostr(); 类名/函数名 record 基类 records wt/rd() input() edt() 设计思想: 此程序是过程性语言设计的。运用多种条件语句,主体采用的是动态数组、指针。系统的设计采用了数组语句、选择语句和循环语句,在需要处理大量同类数据时,这样就使程序书写更加简洁。程序使用了布尔函数。选择语句多采用if多分支选择结构与switch语句。首先计算switch表达式,然后在caes子句中寻找值相等的常量表达式,并以此为入口符号,由此开始顺序执行。循环语句采用了for语句等、do-while语句,for语句用于已知循环次数的循环结构,括号中的三个量分别用来表示循环变量初值、循环终值和循环增量。do-while语句先循环后判断, Break语句在switch语句中,保证多分支情况的正确执行,在循环语句中,强制终止本层循环。保存和读取函数是典型的函数功能,一个程序是由若干个函数组成的,保存和读取函数是和其他函数互相调用的 再有使用有关类的设计,学生缺课信息类和有关信息排序类,如下: class record //学生缺课信息类 { public: void set(string d,int cno,string c,string s,int type) {
描述 类名/函数名 edt() del() search() search_s() main() 描述 修改学生信息 删除学生信息 查找学生信息 一定范围查找学生信息 主函数 实现学生旷课情况排序的类 实现对文件的输入和输出 录入学生的缺课记录 修改学生信息 date.assign(d);//日期 cname.assign(c);//课程名字 sname.assign(s);//学生姓名 this->cno=cno;//对缺课类型的选择 为int型 this->type=type;//缺课类型 4
}
void set(record re) { date.assign(re.date); cname.assign(re.cname); sname.assign(re.sname); this->cno=re.cno; this->type=re.type;
}
string date,cname,sname; int cno,type; };
class records //实现学生旷课情况排序的类{ public:
records() //构造函数 { r=new record[100]; n=0;
}
void order_s() //姓名的排序 { int i;
int j;
string *s=new string[n]; int *c=new int [n]; s[0].assign(r[0].sname); c[0]=1; int k=1,flag; for( i=1;i 5 flag=1; break; } if(!flag) { s[k]=r[i].sname; c[k++]=1; } } for(i=1;i } } cout<<\"旷课学生姓名\旷课次数\"< void order_c() //课程排序 { int i,j; string *s=new string[n]; int *c=new int [n]; s[0].assign(r[0].cname); c[0]=1; int k=1,flag; for( i=1;i 6 } } for(j=0;j if(r[i].cname==s[j]) { } c[j]++; flag=1; break; if(!flag) for(i=1;i if(c[j]>c[j-1]) { } int tmp=c[j]; c[j]=c[j-1]; c[j-1]=tmp; string stmp=s[j]; s[j]=s[j-1]; s[j-1]=stmp; cout<<\"课程名\旷课人次\"< 把所有的学生记录都保存到一个文件里面,然后根据需要再将里面需要查找的元素进行查找,相应的排序可能就是将他们尽可能压进关联式容器map,有的部分就压入set里面,这些都是根据模块的功能来选定的。可以这么说,选择好合理的数据结构查找与排序就可以一劳永逸了。这点在后面部分会有详细的说明。还有就是对各功能子函数的编写应用。 7 2.对功能的实现: (1)、录入学生的缺课记录,函数代码void input(records *r){}模块中。首先提示用户按照正确的格式进行学生缺课记录的录入,这个步骤比较简单,只需要不断地将记录的每个数据项存入结构体对应的成员中。 (2)、修改某个学生的缺课记录,函数代码void edt(records *r){}模块中。首先必须查找到你所需要修改的那位的学生全部缺课记录。这个模块不需要定义新的结构体。在修改前当然要检查记录是否为空了,不为空的话,可以设置下面这五个菜单供用户选择:1、缺课日期2、第几节课3、课程名称4、学生姓名5、缺课类型6、退出修改程序并返回系统主菜单。修改很简单,仅需要对该学生的某个部分进行替换即可。采用switch语句很快就解决。最后实现对所选记录的修改,完成后更新原有的学生记录。 (3)、查询某个学生的缺课情况,函数代码void search(records *r){}模块中。达到查询结果按照日期升序排序,同一天内按照所缺课程的时间升序排序的目的, (4)、统计,函数代码为void order_c(){}和void order_s(){}的类模块中。其中实现对课程排序和对学生姓名的排序。 三、 用户手册 使用时根据提示进行选择和输入操作,当输入有误时会出现“输入有误,重新输入!”。首先进入程序是会有提示输入下面序号,序号后面的文字代表选择某序号后的功能。 1.显示所有学生的缺课记录 2.录入学生的缺课信息记录 4.修改某个学生的缺课记录 5.删除某个学生的缺课记录 6.统计某段时间内旷课情况 7. 退出系统 3.查询某个学生的缺课情况 四、 调试及测试 当用户执行程序时首先会出现如下界面也是主菜单界面: 8 当输入序号1时会出现所有学生记录: 再选择y就会又回到主菜单界面,选n时就会退出。 当在主菜单是选择序号2时就会出现如下界面: 9 按照提示进行输入,如果要继续输入则选择y,否则选n推出并会提示是否保存录入的内容。 当在主菜单是选择序号3时会出现界面: 10 此时就要求输入查询的学生姓名,输入之后如果记录没有就会出现“没有查到该学生的缺课纪录”,如果有的话就会显示次学生的记录。 当在主菜单是选择序号4时,就会提示输入需要修改的姓名,如果此学生有会出现: 如果没有此学生就会出现: 11 同样在主菜单选择5时会出现: 选择6时则会出现界面: 12 在统方式选1的话会出现上面的界面,选2的话界面如下: 当选择7时:就会退出系统如果想再次使用就必须再次打开程序选择功能使用。 13 五、小结 本次课程设计主要使用到了C++中的一些比较基本的算法,总体上感觉比之前做过的实验综合性比较强。在这里我主要总结一下我设计这个学生考勤管理系统的心得和在编译程序的过程中遇到的问题以及解决的办法。 为了使得程序的编写更加有条理,阅读更加明了,在写每个模块的时候都将自己的思路写在每个函数的第一行,告诉自己(读者)我这个函数将要做的是什么事情。这是一个很好的编程规范,值得继续发扬。 对于这次的程序的编写,花了不少时间,原因很可能是自己对C++的总体认知还不够,还有在上学期一个月对C++的学习知识量很有限,在编写调试的这个过程中很多新的语法知识都是在网上搜索的。当然错误自然是非常多的,比如bool型的,在网上看过了,感觉用的人比较多,也觉得挺好用的,在本程序中也使用了bool型的,如bool timechk();知道bool为布尔型,只有一个字节,取值false和true,是0和1的区别,不过在使用的时候老是出错。还有使用append()添加文本常用方法:直接添加另一个完整的字符串,如str1.append(str2);添加另一个字符串的某一段子串:如str1.append(str2, 11, 7); 添加几个相同的字符:如str1.append(5, '.');注意,个数在前字符在后.上面的代码意思为在str1后面添加5个\".\". 再比如类的数据成员的初始化可以采用初始化表或函数体内赋值两种方式,这两种方式的效率不完全相同。非内部数据类型的成员对象应当采用第一种方式初始化,以获取更高的效率。内部数据类型的数据成员而言,两种初始化方式的效率几乎没有区别,但后者的程序版式似乎更清晰些。不能在类声明中初始化const 数据成员,类的const 常量只能在初始化表里被初始化。 在设计好思路以后就是测试数据的设计,不过本次实验的测试数据比较死板,没什么好变动的。 我学习编程一直有自己的一点想法:用任务来牵引,在实践中学习。也就是说,我没有按照某种固定的顺序去学习编程,而是经常有一些小的程序想法或是想编一个满足特定功能 14 的程序。这样刚开始几乎每次都是在对所编程序一无所知的基础上进行,由简单到复杂,一个问题一个问题地去解决。当然,很多时候我失败了,但在这过程中,我学到了很多。问题一个个地解决,知识一点点地积累,经验一点点地丰富,想法一点点地成熟,成功概率也一点点地提高。现在编写一些简单的桌面应用程序也基本上没有问题了。 首先声明,虽然我不是什么高手,不过通过这次编写这样的系统的学习我还是有一点心得的。学编程急不得,上来就学VC肯定碰一头灰,说VC难就难在这点上了。如果硬上,意志坚强的话也许能挺过来,但也是会缺乏后劲,不得不回过头来补习基础知识。意志不坚强的话,很有可能就此放弃了,并留下一个VC难得不得了的印象。其实,只要踏踏实实一步一步来,VC也就是很简单点事。在这里我说一下,如果你还只是一个初中生,那么你就应当仔细考虑一下了。首先,限于你的知识和思维能力,学学C语言还应该没问题,但要学VC是要下相当大的功夫的。而且,你现在学到的东西将来一定会过时,所以不如把精力放在算法的研究上,毕竟这些东西永远都不会过时。 由于时间把握不好,这个系统是在几天空余时间写出来的,难免有点仓促,任然有许多需要改进的方向,但基本的功能已经达到了。 最后,通过完成编程,我达到了: 1. 加深对本课程理论知识的理解,提高实际应用能力; 2. 树立自身对理论联系实际的工作作风、严肃认真的科学态度; 3. 进一步训练和提高自身的分析设计能力、理论计算能力、实验研究能力、外文阅读、查阅文献资料和文字表达等基本技能; 4. 培养自身分析、解决实际问题的能力,培养自身的创新意识和创新能力。 六、参考文献 [1].郑莉 等编著《C++语言程序设计(第三版)》北京:清华大学出版社 [2].郑莉 等编著《C++语言程序设计(第三版)学生用书》北京: 清华大学出版社 [3].李春葆 等编著《C++程序设计学习与上机实验指导》 北京:清华大学出版社 [4].范辉 等编著《Visual C++6.0程序设计简明教程》 高等教育出版社 [5].李龙澍《C++程序设计实训教程》北京:清华大学出版社 [6].洪国胜 等编著 《C++ Builder程序设计轻松上手》北京:清华大学出版社 [7].严蔚敏等 《数据结构(c语言版)》 北京:清华大学出版社,1997年4月第1版。 [8].胡学钢等《数据结构算法设计指导》北京:清华大学出版社,1999年 第1版。 附录源程序代码 第一部分: 学生考勤管理系统.cpp #include \"stdlib.h\" #include \"hanshushixian.h\" #include \"record.h\" 15 #include int main() { 16 c1: //主菜单实现 system(\"cls\"); { cout<<\" *************************************************************\"< *************************************************************\"< *************************************************************\"< cout<<\" *** 系统主菜单: 1.显示所有学生的缺课记录 cout<<\" *** 2.录入学生的缺课信息记录 cout<<\" *** 3.查询某个学生的缺课情况 cout<<\" *** 4.修改某个学生的缺课记录 cout<<\" *** 5.删除某个学生的缺课记录 cout<<\" *** 6.统计某段时间内旷课情况 cout<<\" *** 7. 退出系统 } cout<<\"O(∩_∩)O 请选择你所需要的操作 O(∩_∩)O: \"< if(chose==7)exit(0); records *r=new records(); rd(r); switch(chose) { case 1:pri(r);break; case 2:input(r);break; case 3:search(r);break; case 4:edt(r);break; case 5:del(r);break; case 6:search_s(r);break; default:goto c2; } cout<<\"是否返回主菜单? (y/n)——你的选择: \"< if(yn=='y')goto c1; else if(yn=='n')exit(0); else goto c3; return 0; } 第二部分:record.h (类的设计部分) #include #ifndef record_class #define record_class 17 class record //关于学生考勤基本信息类 { public: void set(string d,int cno,string c,string s,int type) { date.assign(d); cname.assign(c); sname.assign(s); this->cno=cno; this->type=type; } void set(record & re) { date.assign(re.date);//assign可以避免不必要的内存分配,可以提高效率 cname.assign(re.cname); sname.assign(re.sname); this->cno=re.cno; this->type=re.type; } string tostr() { string s; char tmp[3]; s.assign(date); itoa(cno,tmp,10); s.append(\"#\"); s.append(tmp);//直接添加另一个完整的字符串 s.append(\"#\"); s.append(cname); s.append(\"#\"); s.append(sname); itoa(type,tmp,10); s.append(\"#\"); s.append(tmp); return s; } 18 string date; string cname; string sname; int cno; int type; }; #endif record_class #ifndef records_class #define records_class class records//实现学生旷课情况排序的类 { public: records() //构造函数 { r=new record[100]; n=0; } void order_s() //姓名的排序 { int i; int j; string *s=new string[n]; int *c=new int [n]; s[0].assign(r[0].sname); c[0]=1; int k=1,flag; for( i=1;i 19 break; } if(!flag) { s[k]=r[i].sname; c[k++]=1; } } for(i=1;i } } cout<<\"旷课学生姓名\旷课次数\"< void order_c() //课程排序 { int i,j; string *s=new string[n]; int *c=new int [n]; s[0].assign(r[0].cname); c[0]=1; int k=1,flag; for( i=1;i if(r[i].cname==s[j]) { c[j]++; flag=1; break; } if(!flag) { s[k]=r[i].cname; c[k++]=1; } } for(i=1;i } } cout<<\"课程名\旷课人次\"< record *r; int n; }; #endif records_class 第三部分:hanshushixian.h (功能子函数的实现部分) 21 #include \"record.h\" #include void wt(records *r)//实现对文件的输出 { ofstream outf(\"data.txt\"); for(int i=0;i outf< void rd(records *r)//实现对文件的输入 { ifstream inf(\"data.txt\"); if(inf.eof()) { cout<<\"记录为空!\"< string t1,t3,t4; char tmp[30]; int t2,t5; r->n=0; while(true) { inf.getline(tmp,10,'#'); if(tmp[0]=='!')break; t1.assign(tmp); inf.getline(tmp,3,'#'); t2=atoi(tmp); inf.getline(tmp,30,'#'); 22 t3.assign(tmp); inf.getline(tmp,30,'#'); t4.assign(tmp); inf.getline(tmp,3); t5=atoi(tmp); r->r[r->n++].set(t1,t2,t3,t4,t5); } } bool timechk(string t1) { int year=atoi(t1.substr(0,2).c_str()); int month=atoi(t1.substr(2,2).c_str()); int day=atoi(t1.substr(4,2).c_str()); if(!(t1.length()==6&&year>0&&year<99&&month>0&&month<13&&day>0&&day<32)) { cout<<\"日期录入有误! 请重新录入: \"< else return true; } void input(records *r)//录入学生的缺课记录 { string t1,t3,t4; int t2,t5,flag=0; char yn; cout<<\"录入一条学生缺课记录:\"< if(!(timechk(t1)))goto m1; m2: cout<<\"请输入缺第几节课: \"< { 23 } cout<<\"节次录入有误! 请重新录入: \"< cout<<\"请输入缺课学生姓名: \"< cout<<\"请输入缺课类型: (1.迟到 2.早退 3.请假 4.旷课) \"< for(int i=0;i if(r->r[i].date==t1&&r->r[i].cno==t2&&r->r[i].cname==t3&&r->r[i].sname==t4&& { } cout<<\"该条记录已存在,是否添加为新记录? (y/n) \"< if(yn=='y')break; else if(yn=='n')goto n2; else goto n1; cout<<\"类型输入有误! 请重新录入: \"< r->r[i].type==t5) n1: r->r[r->n++].set(t1,t2,t3,t4,t5); cout<<\"是否继续输入? (y/n) \"< if(yn=='y')goto m1; else if(yn=='n') { cout<<\"保存修改? (y/n) \"< 24 n2: n3: if(yn=='y')wt(r); else return; } else goto n3; } void prione(record r) { cout< { case 1:cout<<\"迟到\"< void pri(records *r)//修改学生信息 { if(r->n==0) { cout<<\"记录为空!\"< cout<<\"\\n序号\缺课日期 节次\课程名称\学生姓名\缺课类型\"< } 25 void edt(records *r)//修改学生信息 { if(r->n==0) { } cout<<\"请输入要修改缺课记录的学生姓名: \"< t1=r->r[i].date; t2=r->r[i].cno; t3=r->r[i].cname; t4=r->r[i].sname; t5=r->r[i].type; cout<<\"请输入要修改的项目:\\n(1.缺课日期 2.缺课节次 3.缺课名称 4.学生姓名 5. cout<<\"查无此学生!\"< flag=7; break; cout<<\"记录为空!\"< 缺课类型 6.全部) \"< 26 { case 1:goto e1; case 2:goto e2; case 3:goto e3; case 4:goto e4; case 5:goto e5; case 6:goto e1; default:goto e0; } e1: cout<<\"请输入缺课日期: (例如080612) \"< if(flag!=6)goto e6; e2: cout<<\"请输入缺第几节课: \"< if(flag!=6)goto e6; e3: cout<<\"请输入缺课名称: \"< if(flag!=6)goto e6; e4: cout<<\"请输入缺课学生姓名: \"< if(flag!=6)goto e6; e5: cout<<\"请输入缺课类型: (1.迟到 2.早退 3.请假 4.旷课) \"< e6: r->r[i].set(t1,t2,t3,t4,t5); char yn; cout<<\"保存修改? (y/n) \"< if(yn=='y')wt(r); else return; } 27 void del(records *r)//删除学生信息 { if(r->n==0) { } cout<<\"请输入要删除的记录的序号: (输入-1删除全部) \"< if(flag>r->n-1&&flag<-1) { cout<<\"不存在所要删除的记录!\"< else if(flag==-1)r->n=0; else { for(int i=flag;i r->r[i].set(r->r[i+1]); r->n--; } char yn; cout<<\"保存修改? (y/n) \"< if(yn=='y')wt(r); else return; } void search(records *r)//查找学生信息 { if(r->n==0) { cout<<\"记录为空!\"< cout<<\"请输入要查询的学生姓名: \"< } string str; int j=0,flag=0; cin>>str; for(int i=0;i if(r->r[i].sname==str) { } if(!flag)cout<<\"\\n序号\缺课日期 节次\课程名称\学生姓名\缺课cout< 类型\"< int i; if(r->n==0) { } records *r1=new records(); cout<<\"请输入要检索的时间范围: (例如110610-110612) \"< ld.assign(tmp.substr(0,6)); hd.assign(tmp.substr(7,6)); if(!timechk(ld)||!timechk(hd))goto g1; for(i=0;i if(r->r[i].date.compare(ld)>=0&&r->r[i].date.compare(hd)<=0&&r->r[i].type==4 r1->r[r1->n++].set(r->r[i]); 29 cout<<\"记录为空!\"< cout<<\"请选择统计方式: (1.学生旷课情况降序显示 2.课程旷课情况降序显 示)\"< case 2: cout<<\"\\n在\"< default:goto g2; } } 注:测试数据和运行结果见 测试与调试 的文字和截图部分。 30 }record *r; int n; };}}
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- vipyiyao.com 版权所有 湘ICP备2023022495号-8
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务