cout<
}
record*r;
intn;
};
把所有的学生记录都保存到一个文件里面,然后根据需要再将里面需要查找的元素进行查找,相应的排序可能就是将他们尽可能压进关联式容器map,有的部分就压入set里面,这些都是根据模块的功能来选定的。
可以这么说,选择好合理的数据结构查找与排序就可以一劳永逸了。
这点在后面部分会有详细的说明。
还有就是对各功能子函数的编写应用。
2.对功能的实现:
(1)、录入学生的缺课记录,函数代码voidinput(records*r){}模块中。
首先提示用户按照正确的格式进行学生缺课记录的录入,这个步骤比较简单,只需要不断地将记录的每个数据项存入结构体对应的成员中。
(2)、修改某个学生的缺课记录,函数代码voidedt(records*r){}模块中。
首先必须查找到你所需要修改的那位的学生全部缺课记录。
这个模块不需要定义新的结构体。
在修改前当然要检查记录是否为空了,不为空的话,可以设置下面这五个菜单供用户选择:
1、缺课日期2、第几节课3、课程名称4、学生姓名5、缺课类型6、退出修改程序并返回系统主菜单。
修改很简单,仅需要对该学生的某个部分进行替换即可。
采用switch语句很快就解决。
最后实现对所选记录的修改,完成后更新原有的学生记录。
(3)、查询某个学生的缺课情况,函数代码voidsearch(records*r){}模块中。
达到查询结果按照日期升序排序,同一天内按照所缺课程的时间升序排序的目的,
(4)、统计,函数代码为voidorder_c(){}和voidorder_s(){}的类模块中。
其中实现对课程排序和对学生姓名的排序。
三、用户手册
使用时根据提示进行选择和输入操作,当输入有误时会出现“输入有误,重新输入!
”。
首先进入程序是会有提示输入下面序号,序号后面的文字代表选择某序号后的功能。
1.显示所有学生的缺课记录
2.录入学生的缺课信息记录
3.查询某个学生的缺课情况
4.修改某个学生的缺课记录
5.删除某个学生的缺课记录
6.统计某段时间内旷课情况
7.退出系统
四、调试及测试
当用户执行程序时首先会出现如下界面也是主菜单界面:
当输入序号1时会出现所有学生记录:
再选择y就会又回到主菜单界面,选n时就会退出。
当在主菜单是选择序号2时就会出现如下界面:
按照提示进行输入,如果要继续输入则选择y,否则选n推出并会提示是否保存录入的内容。
当在主菜单是选择序号3时会出现界面:
此时就要求输入查询的学生姓名,输入之后如果记录没有就会出现“没有查到该学生的缺课纪录”,如果有的话就会显示次学生的记录。
当在主菜单是选择序号4时,就会提示输入需要修改的姓名,如果此学生有会出现:
如果没有此学生就会出现:
同样在主菜单选择5时会出现:
选择6时则会出现界面:
在统方式选1的话会出现上面的界面,选2的话界面如下:
当选择7时:
就会退出系统如果想再次使用就必须再次打开程序选择功能使用。
五、小结
本次课程设计主要使用到了C++中的一些比较基本的算法,总体上感觉比之前做过的实验综合性比较强。
在这里我主要总结一下我设计这个学生考勤管理系统的心得和在编译程序的过程中遇到的问题以及解决的办法。
为了使得程序的编写更加有条理,阅读更加明了,在写每个模块的时候都将自己的思路写在每个函数的第一行,告诉自己(读者)我这个函数将要做的是什么事情。
这是一个很好的编程规范,值得继续发扬。
对于这次的程序的编写,花了不少时间,原因很可能是自己对C++的总体认知还不够,还有在上学期一个月对C++的学习知识量很有限,在编写调试的这个过程中很多新的语法知识都是在网上搜索的。
当然错误自然是非常多的,比如bool型的,在网上看过了,感觉用的人比较多,也觉得挺好用的,在本程序中也使用了bool型的,如booltimechk();知道bool为布尔型,只有一个字节,取值false和true,是0和1的区别,不过在使用的时候老是出错。
还有使用append()添加文本常用方法:
直接添加另一个完整的字符串,如str1.append(str2);添加另一个字符串的某一段子串:
如str1.append(str2,11,7);
添加几个相同的字符:
如str1.append(5,'.');注意,个数在前字符在后.上面的代码意思为在str1后面添加5个".".
再比如类的数据成员的初始化可以采用初始化表或函数体内赋值两种方式,这两种方式的效率不完全相同。
非内部数据类型的成员对象应当采用第一种方式初始化,以获取更高的效率。
内部数据类型的数据成员而言,两种初始化方式的效率几乎没有区别,但后者的程序版式似乎更清晰些。
不能在类声明中初始化const数据成员,类的const常量只能在初始化表里被初始化。
在设计好思路以后就是测试数据的设计,不过本次实验的测试数据比较死板,没什么好变动的。
我学习编程一直有自己的一点想法:
用任务来牵引,在实践中学习。
也就是说,我没有按照某种固定的顺序去学习编程,而是经常有一些小的程序想法或是想编一个满足特定功能的程序。
这样刚开始几乎每次都是在对所编程序一无所知的基础上进行,由简单到复杂,一个问题一个问题地去解决。
当然,很多时候我失败了,但在这过程中,我学到了很多。
问题一个个地解决,知识一点点地积累,经验一点点地丰富,想法一点点地成熟,成功概率也一点点地提高。
现在编写一些简单的桌面应用程序也基本上没有问题了。
首先声明,虽然我不是什么高手,不过通过这次编写这样的系统的学习我还是有一点心得的。
学编程急不得,上来就学VC肯定碰一头灰,说VC难就难在这点上了。
如果硬上,意志坚强的话也许能挺过来,但也是会缺乏后劲,不得不回过头来补习基础知识。
意志不坚强的话,很有可能就此放弃了,并留下一个VC难得不得了的印象。
其实,只要踏踏实实一步一步来,VC也就是很简单点事。
在这里我说一下,如果你还只是一个初中生,那么你就应当仔细考虑一下了。
首先,限于你的知识和思维能力,学学C语言还应该没问题,但要学VC是要下相当大的功夫的。
而且,你现在学到的东西将来一定会过时,所以不如把精力放在算法的研究上,毕竟这些东西永远都不会过时。
由于时间把握不好,这个系统是在几天空余时间写出来的,难免有点仓促,任然有许多需要改进的方向,但基本的功能已经达到了。
最后,通过完成编程,我达到了:
1.加深对本课程理论知识的理解,提高实际应用能力;
2.树立自身对理论联系实际的工作作风、严肃认真的科学态度;
3.进一步训练和提高自身的分析设计能力、理论计算能力、实验研究能力、外文阅读、查阅文献资料和文字表达等基本技能;
4.培养自身独立分析、解决实际问题的能力,培养自身的创新意识和创新能力。
六、参考文献
[1].郑莉等编著《C++语言程序设计(第三版)》北京:
清华大学出版社
[2].郑莉等编著《C++语言程序设计(第三版)学生用书》北京:
清华大学出版社
[3].李春葆等编著《C++程序设计学习与上机实验指导》北京:
清华大学出版社
[4].范辉等编著《VisualC++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"
#include
#include
#include
#include
usingnamespacestd;
#include"record.h"
intmain()
{
c1:
//主菜单实现
system("cls");
{
cout<<"*************************************************************"<cout<<"***★欢迎访问学生考勤管理系统★***"<cout<<"*************************************************************"<cout<<"***系统主菜单:
1.显示所有学生的缺课记录***"<cout<<"***2.录入学生的缺课信息记录***"<cout<<"***3.查询某个学生的缺课情况***"<cout<<"***4.修改某个学生的缺课记录***"<cout<<"***5.删除某个学生的缺课记录***"<cout<<"***6.统计某段时间内旷课情况***"<cout<<"***7.退出系统***"<cout<<"*************************************************************"<}
cout<<"O(∩_∩)O请选择你所需要的操作O(∩_∩)O:
"<intchose;
c2:
cin>>chose;
if(chose==7)exit(0);
records*r=newrecords();
rd(r);
switch(chose)
{
case1:
pri(r);break;
case2:
input(r);break;
case3:
search(r);break;
case4:
edt(r);break;
case5:
del(r);break;
case6:
search_s(r);break;
default:
gotoc2;
}
cout<<"是否返回主菜单?
(y/n)——你的选择:
"<charyn;
c3:
cin>>yn;
if(yn=='y')gotoc1;
elseif(yn=='n')exit(0);
elsegotoc3;
return0;
}
第二部分:
record.h(类的设计部分)
#include
#include
usingnamespacestd;
#ifndefrecord_class
#definerecord_class
classrecord//关于学生考勤基本信息类
{
public:
voidset(stringd,intcno,stringc,strings,inttype)
{
date.assign(d);
cname.assign(c);
sname.assign(s);
this->cno=cno;
this->type=type;
}
voidset(record&re)
{
date.assign(re.date);//assign可以避免不必要的内存分配,可以提高效率
cname.assign(ame);
sname.assign(re.sname);
this->cno=o;
this->type=re.type;
}
stringtostr()
{
strings;
chartmp[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);
returns;
}
stringdate;
stringcname;
stringsname;
intcno;
inttype;
};
#endifrecord_class
#ifndefrecords_class
#definerecords_class
classrecords//实现学生旷课情况排序的类
{
public:
records()//构造函数
{
r=newrecord[100];
n=0;
}
voidorder_s()//姓名的排序
{
inti;
intj;
string*s=newstring[n];
int*c=newint[n];
s[0].assign(r[0].sname);
c[0]=1;
intk=1,flag;
for(i=1;i{
flag=0;
for(j=0;jif(r[i].sname==s[j])
{
c[j]++;
flag=1;
break;
}
if(!
flag)
{
s[k]=r[i].sname;
c[k++]=1;
}
}
for(i=1;ifor(j=i;j>0;j--)
{
if(c[j]>c[j-1])
{
inttmp=c[j];
c[j]=c[j-1];
c[j-1]=tmp;
stringstmp=s[j];
s[j]=s[j-1];
s[j-1]=stmp;
}
}
cout<<"旷课学生姓名\t旷课次数"<for(i=0;icout<
}
voidorder_c()//课程排序
{
inti,j;
string*s=newstring[n];
int*c=newint[n];
s[0].assign(r[0].cname);
c[0]=1;
intk=1,flag;
for(i=1;i{
flag=0;
for(j=0;jif(r[i].cname==s[j])
{
c[j]++;