课程设计报告c++学籍管理.docx
《课程设计报告c++学籍管理.docx》由会员分享,可在线阅读,更多相关《课程设计报告c++学籍管理.docx(22页珍藏版)》请在冰点文库上搜索。
![课程设计报告c++学籍管理.docx](https://file1.bingdoc.com/fileroot1/2023-4/30/ead447fb-ac92-4744-ab3c-a5b6f3d2ee4d/ead447fb-ac92-4744-ab3c-a5b6f3d2ee4d1.gif)
课程设计报告c++学籍管理
成绩
课程设计报告
题目学籍信息管理
课程名称面向对象程序设计课程设计
院部名称软件工程学院
专业软件工程
班级13软件工程2班
学生姓名葛石
学号1305104061
课程设计地点1318
课程设计学时20学时
指导教师李尤丰
金陵科技学院教务处制
一、课程设计的目的和要求
该课程设计的目的采用面向对象的程序设计语言,开发实现一个应用程序,主要目的是使学生更好的掌握面向对象程序设计语言及其开发工具,掌握如何使用面向对象的程序设计语言设计一个小的软件系统。
通过该课程设计培养学生分析和解决实际问题的能力,培养学生综合应用基本概念,基本原理,和技术方法的能力,真正做到学以致用,使课本上抽象的理论,方法与具体的实践应用相结合。
注意自始至终贯彻课程中所介绍的程序设计风格,养成良好的编程习惯。
应独立完成所布置的上机作业,为保证尽量在统一安排的上机时间内编译运行通过程序,应事先预习设计好程序。
课后撰写实验报告。
2、系统需求分析
编写一个学籍信息管理程序。
学籍信息的组成部分为:
学号、姓名、性别、出生日期、家庭住址、就读学校、就读小学、中学和成绩等。
此学籍信息管理主要利用类和单链表实现,完成的功能主要有如下十大功能模块组成:
(1)清空学生信息
该模块完成清除所有学生信息的功能。
在菜单栏里选择1,清空信息。
(2)增加学生信息模块
该模块主要由单链表和类来完成,比较简单,在菜单栏里选择2,进入增加界面。
根据提示信息,输入相应的学生信息。
(3)删除学生信息模块
该模块完成根据学号删除指定学生信息,它分两部分完成。
第一步,根据输入的学号调用linkFindid(),判断该学生是否存在。
第二步,若不存在,输出“没有找到学号为i的学生记录!
”,若存在,删除该学生全部信息。
(4)查找学生信息模块
该模块完成根据学号、姓名、专业或性别查找指定学生的信息。
进入查找模块,选择1为按学号查找,2为按姓名查找,3为按专业查找,4为按性别查找。
若存在,显示查找结果;若不存在,显示未找到相关学生。
(5)显示学生信息模块
由主菜单进入显示界面,显示已经输入的全部学生信息。
(6)保存学生信息模块
在主菜单中选择6保存所有学生信息。
(7)统计学生信息
该模块完成按平均分统计学生的功能
(8)修改学生信息模块
该模块完成根据学号修改指定学生信息,它也分两部分完成。
第一步,根据输入的学号调用linkFindid(),判断该学生是否存在。
第二步,若不存在,输出“未找到相关学生”,若存在,按步骤修改该学生信息。
(9)修改登录密码模块
该模块用来修改登录密码。
(10)退出模块
该模块完成安全退出的功能。
在退出之前询问是否保存数据。
三、总体设计
学籍管理系统,需要管理一个班级的学生的信息。
首先,我们需要设计一个学生类,因为从面向对象的角度来说,每个人都是一个类的对象。
在具体的实现时,我们发现,采用顺序表即数组的形式是不合适的,因为内存中不一定会有这么大的连续的一块存储空间可以申请,由此,我们想到了使用链表。
在设计类时,我们采用模仿显示世界的情况来设计学生类,每一个学生作为一个Node对象,在学生类中使用link类来表示学生之间的联系。
其次,我们在设计系统功能的时候模仿了数据库的功能。
例如增添,查找,删除,修改等等。
这些功能主要由学生类中的函数调用成员类link的函数来实现。
为了提高程序的封装性,我们用link类中的函数实现底层功能,而将具体的高级功能用学生类来实现。
最后我们在设计系统界面的时候为了美化界面,提升用户体验,尽量将界面居中对齐,在用户输入时做出必要的提示,并且为菜单加上了边框。
以下是系统功能图:
以下是类的结构:
Link类的函数介绍:
Link();//构造函数,初始化变量
boollinkIsEmpty();//判断链表是否为空
voidlinkInsert(Node*newnode);//向链表中插入新的结点
boollinkDelete(intnid);//从链表中删除的结点
voidlinkClear();//清空链表中数据
voidlinkView();//查看链表中数据
voidlinkGrade(Node*p1);//计算等级
voidlinkAverageTotle();//按平均分统计
Node*linkFindid(intnid);
//在链表中查找id为nid结点,返回指向结点的指针
Node*linkFindname(stringxm);//按姓名查找,返回指向结点的指针
Node*Link:
:
linkFindname(Node*p,stringxm);
//按姓名查找,返回指向结点的指针,是重载函数
Node*linkFindsex(stringxb);//按性别查找,返回指向结点的指针
Node*Link:
:
linkFindsex(Node*p,stringxb);
//按姓名查找,返回指向结点的指针,是重载函数
Node*linkFindzy(stringzy);//按专业查找,返回指向结点的指针
Node*Link:
:
linkFindzy(Node*p,stringzy);
//按专业查找,返回指向结点的指针,是重载函数
Node*getHead();//获取头指针
Student类的函数介绍:
Student();//构造函数,初始化对象
intgetlanding(void);//登陆函数
voidchangepassword(void);//修改密码函数
voidstudentClear();//清空数据
voidstudentInsert();//插入新的数据
voidstudentDelete();//删除数据
voidstudentFind();//查找指定条件的学生
voidstudentView();//查看所有学生记录
voidstudentLoad();//加载文件中的学生记录
voidstudentSave();//保存链表中的学生数据到文件
voidstudentChange();//修改链表中的学生数据
voidstudentAverageTotle();//按平均分数统计等级
voidExit();//先保存,再退出程序
voidshowMenu();//显示主菜单
voidshowTip();//显示操作提示,提示用户输入
voiddoMenu(charn);//执行相应菜单项功能,识别用户选项
4、详细设计
我主要负责密码登陆部分和修改学生数据部分。
首先是密码部分,这个部分的主要功能是实现用户的登陆和密码修改。
需要解决的是如何将用户输入的密码和实际的用户密码进行对比配对。
要实现这个功能,我的设计思路是将正确的密码保存在文件中,当用户登陆的时候就将密码从文件取出,并和用户输入的密码进行配对,如果成功匹配,则登陆系统,否则提示用户密码输入错误,要求再次输入。
三次输入不正确则自动退出系统,这是对于系统安全的一种保障。
密码的登陆功能作为一个函数写在Student类里,每次登陆系统自动调用。
为了可以让密码具有复杂性,难以被暴力破解,除了有三次输入机会的保障外,我选择使用字符串作为密码的变量类型,这样用户就可以使用任意复杂的字符来设置密码,大大提高了密码的安全性。
此外,用户第一次使用系统时,系统加载密码文件时将读不到账户密码,此时系统将自动赋予初始的账户密码。
以下是部分关键代码:
getfile>>realaccount;//使用文件流进行账户密码的文件读入
getfile>>realpassworld;
if(strlen(realaccount)==0&&strlen(realpassworld)==0)//读不到账户密码时
{
strcpy(realaccount,"geshi");//自动赋予初始的账户密码
strcpy(realpassworld,"123456");
}
while(n--)//n设置为3,最多输入三次
if(strcmp(myaccount,realaccount)==0)
//用户的输入与真实的账户密码相同时则退出函数,并登陆系统
{
if(strcmp(mypassworld,realpassworld)==0)
{
return1;
}
}
在用户登陆之后,可以根据主菜单的提示进行选择,修改账户的密码。
在实现这个功能时,需要首先保存新的密码,其次要讲密码保存到密码文件中。
在获得用户输入的新密码时,我们必须要先清理缓冲区域的用户输入残留,例如诸多的空格,回车等等,以防系统将这些也作为新密码的组成元素读入新密码中造成混乱。
以下是部分代码和注释:
cout<<"请输入新的密码:
";
fflush(stdin);//清空缓冲区数据
cin>>newpassword;//输入新的密码
ofstreamoutfile("landing.txt");//打开密码文件
outfile<cout<<"密码修改成功!
";//提示修改成功
在修改部分,我主要运用的是switch函数和之前定义好的link类中的linkfind()查找函数。
按照惯例,首先检查系统中是否有学生数据。
其次,提示用户输入需要修改的学生的学号。
在这里我使用的是仿照数据库的主键的定义,将学生的学号作为唯一的主键用以表示各个学生,一边操作。
用户输入学生学号之后,将会有界面提示选择修改的学生的各项属性,同时提示可修改的属性选项进行选择修改,在用户选择之后,使用switch函数来判断用户的选择。
在选择好之后就是一系列的提示输入和修改选项。
值得一说的是在对于学号的修改中,由于学号是作为主键来唯一标示学生的,所以不能有两个完全一样的学号存在,因此,需要在用户要修改学号时,若是新的学号已存在,则提示用户重新输入。
以下是部分代码:
fflush(stdin);//清空缓冲区数据
cin>>nid;//输入需要修改的学生的学号
p=slink.linkFindid(nid);//查找到该学生,使用指针指向他
if(p)//如果指针不空,即该学生存在时进行提示修改学生信息
while
(1)//输入的学号已经存在时,提示用户重新输入
{
cout<<"请输入新的学号:
";
cin>>nid;
if(slink.linkFindid(nid))
{
cout<<"学号已经存在,请重新输入!
"<}
else
{
p->id=nid;//学号不存在时则修改后跳出循环
break;
}
}
break;
五、测试、调试过程
1.密码登陆部分,使用string类时无法使用strcmp()函数进行匹配比较。
我更改了密码的数据类型,使用了char类型。
因为strcmp()函数的两个参数必须要是char类型的指针。
2.在用户输入密码时,总是无法正确的读取用户输入的密码账号,有时甚至直接就回跳过用户输入界面,提示输入错误。
使用fflush()函数清空缓冲区的数据,以免上一次输入时残留的回车字符对本次输入造成影响。
因为回车字符也是一种字符,会被自动读入,这个时候系统就会认为用户已经输入,输入了一个回车。
在这里不能使用getchar()进行读取,因为getchar()一次就只能读取一个字符,而我们并不知道一共有多少个回车字符残留在缓冲区。
3.登陆修改密码后,密码文件中的密码显示的是乱码,下一次将无法登陆
使用二进制模式打开文件。
因为计算机默认的模式就是二进制,如果人为的改变这个模式有时候就会和打开的文件的存储模式不一致,造成乱码的情况,而二进制是计算机所有文件都可以识别的模式,因此使用二进制是最好的选择。
4.系统首次使用的时候无法登陆
编写代码实现自动设置初始账户密码。
由于是第一次使用,密码文件中是没有账户密码的,系统匹配时就会匹配不成功,从而无法登陆。
5.在用户输入超过三次错误密码后无法显示提示重启系统的信息
使用Sleep(900)函数使系统休眠900毫秒。
提示信息提示之后系统就会自动退出,由于间隔时间太过短暂,造成了没有提示信息的错觉。
这里使用函数让系统休眠一下,能够很好的提升用户体验。
以下是系统各个功能的截图:
图1文件加载对话框
图2密码登陆对话框
图3系统主菜单对话框
图4添加信息对话框
图5删除信息对话框
图6查找主界面对话框
图7按学号查找对话框
图8按姓名查找对话框
图9按性别查找对话框
图10按专业查找对话框
图11显示所有学生数据对话框
图12统计数据对话框
图13修改信息主界面
图14学号纠错功能对话框
图15修改专业对话框
图16密码修改对话框
图17密码文件
6、结论与体会
经过这次的C++课设,我们对C++语言中函数、类与面向对象以及函数的调用关系等内容有了一个更加深刻的认识。
在调试过程中还认识到C++语言在编写程序的过程中需要非常细心和严谨的态度,并且要有足够的耐心,否则就会出现很多问题!
这就需要我们有耐心,一步一步的来,问题终究会解决。
从理论到实践,在将近一个月的日子里,可以说得是苦多于甜,但是可以学到很多很多的的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
本程序涉及的知识虽然简单,却也是C++语言必备的基本知识。
在做课程设计的过程中,我见识到了C++语言的重要性和我在程序设计方面的不足,让我了解到要把书本知识转换为可以实际操作的东西是需要扎实的理论基础和严谨的逻辑思维的,同时我也发现了平时很多没有注意到的问题,弥补了我C++语言方面的不足,我必须用心的一个一个分析,调试,每一次的调试成功,都带给了我莫大的欣喜。
通过这次的C++的课程设计使我们懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。
在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,通过实践的学习,我认到学好计算机要重视实践操作,不仅仅是学习C++语言,还是其它的语言,以及其它的计算机方面的知识都要重在实践,所以后在学习过程中,我会更加注视实践操作,使自己便好地学好计算机。
让我感受最深的一点是:
以前上实验课时,只是注重如何编写函数能够完成所需要的功能,似乎没有明确的战术,只是凭单纯的意识和简单的语句来堆砌出一段程序。
感觉有点像张飞打仗——有勇无谋,只要能完成任务就行。
但现在编程感觉完全不同了。
在编写一个程序之前,自己能够综合考虑各种因素,首先选取自己需要的数据结构,是树图或是别的什么图?
然后选定一种或几种储存结构来具体决定后面的函数的主要风格。
最后在编写每一个函数之前,可以仔细斟酌比对,挑选出最适合当前状况的算法。
这样,即使在完整程序还没有编写出来之前,自己心中已经有了明确的原图了。
这样无形之中就提高了自己编写程序的质量。
同时在此次C++课程设计中也或得了一些经验,将其罗列如下:
1.调试程序的时候有简单到复杂:
碰到程序运行出错时,可以先把不关联的那部分程序注释掉,只留下与问题相关联的一部分,确保程序运行正确后,然后在逐段将代码释放,这样变很容易发现问题所在。
2.有错误的程序会莫名其妙的运行正常,但你并没有找到出错的原因。
这时千万不要高兴太早,应该继续调试和试验,一定要把错误找出来。
只要你找不出这个错误来,这个错误将会成为一个不定时的炸弹,不一定什么时候会爆炸。
7、参考文献
[1](美)戴特尔(Deitel,H.M.).C++大学基础教程(第五版)[M].北京:
电子工业出版社,2007.6
[2]谭浩强C++程序设计[M].北京:
清华大学出版社,2006
[3]古万荣visualc++完全自学手册机械工业出版社,2009
[4]雷进辉visualc++项目开发案例精粹电子工业出版社2010
[5]郑莉C++语言程序设计清华大学出版社2013
附录:
源程序