南京理工大学C课程设计工资管理.docx
- 文档编号:15763066
- 上传时间:2023-07-07
- 格式:DOCX
- 页数:32
- 大小:22.77KB
南京理工大学C课程设计工资管理.docx
《南京理工大学C课程设计工资管理.docx》由会员分享,可在线阅读,更多相关《南京理工大学C课程设计工资管理.docx(32页珍藏版)》请在冰点文库上搜索。
南京理工大学C课程设计工资管理
C++课程设计报告
姓名王镇窑学号913104680120班级9131046801
任课教师钱芸生时间2014.4
实验题目工资管理评定难易级别A
实验报告成绩
一.题目名称:
工资管理
二.难度等级:
A级
三.课程设计要求:
1.用类的形式改写程序,将程序中工资数据用链表的形式存放,定义一个链表类,封装主要操作函数。
2.显示,修改,删除数据项时大小写通用。
3.工资数据按工资值的大小进行排序存放。
4.修改、删除数据前增加提示信息,用户确认后才能进一步操作,否则操作取消。
5.增加程序的文件输入输出功能,在执行程序中首先将工资数据从文件中读出再进行管理,在程序结束时能将工资数据保存在原文件中。
四.程序结构框图
功能示意图:
开始程序,打开文件,把文件中数据读出写入内存中。
文件不存在,则提示。
按0结束程序,将修改后的链表数据从内存中存到文件里。
退出程序。
5.根据姓名修改工资记录。
4.根据姓名删除工资记录。
3.根据姓名查询工资记录。
2.显示工资记录。
主菜单
1.添加工资记录。
返回主菜单
返回主菜单
开始程序
主函数具体流程:
建立一个链表类对象
运行函数将文件中的数据写入内存中,
如果不存在文件输出提示
输出主菜单内容
从键盘提取字符
判断字符是不是0
不是0
是
调用链表类函数实现添加工资记录的功能。
判断是不是1
调用链表类函数把整个链表打印出来。
不是1
是0
是
判断是不是2
调用链表类函数,键盘输入姓名查找出相应的结点,并打印出来。
不是2
是
判断是不是3
不是3
调用链表类函数,键盘输入姓名查找出相应的结点,修改上一节点的next指针删除结点。
是
判断是不是4
不是4
调用链表类函数,键盘输入姓名查找出相应的结点,重新输入工资,赋值给相应的数据类。
是
判断是不是5
调用链表类函数将数据从
内存转存到文件中。
结束程序
五.程序设计思想
整个程序是我和吴龙生同学合作完成,我们先完成了主函数的编写,再把程序各个功能的实现交由类函数实现。
一共有1.添加工资记录。
2.显示工资记录。
3.根据姓名查询工资记录。
4.根据姓名删除工资记录。
5.根据姓名修改工资记录,再加上从文件写入内存,从内存写入文件,七个主要功能函数,我们把这些函数分工编写,再整合整个程序。
用类改编程序,我们建立了一个数据类(用于存放姓名和工资),一个结点类(存放数据类指针和下一个结点的指针),一个链表类(存放链表的头指针和结点的个数,同时封装了对链表操作的所有函数)。
虽然各个程序有不同的具体要求,但链表的操作大同小异,所不同的只是结点那部分的数据类型不同。
所以根据这一特点,可以将链表定义成一个类,涉及结点数据的输入、输出、复制等。
在结点中涉及较多的是具体数据的形式,所以将具体的数据形式定义成数据类型的指针,所有针对数据的操作都转换为对指针的操作,在数据类中再具体实现。
这样,结点的操作也可以像链表一样通用。
最后,再将数据具体形式定义成一个类,涉及数据的输入格式、输出形式、比较内容的大小等。
那么,针对不同的数据管理,只要改动这部分就可以了。
这样就实现程序的结构化了!
主函数,开始运行先建立一个链表类类对象,将文件中的数据读到内存中。
然后再输出整个主菜单,键入相应的命令执行相应的链表类函数实现功能。
最后再把修改后的链表中的数据写入文件中,退出。
六.程序重要功能的实现方法
1.添加工作记录,工资数据按工资值的大小进行排序存放。
主菜单中添加工资记录的功能会先调用链表类Clist的成员函数voidAddRecord()。
该函数会生成一个数据类成员和一个结点类成员,通过键盘输入员工的姓名和工资,并把数据赋值给数据类成员把数据类成员的指针赋给结点类成员,然后再调用Clist的成员函数voidinlist(CNode*node0),并把新生成的结点类指针传递过去,该函数会在原有链表中通过工资数据的比较,按工资大小顺序给该结点找到位置并插入到原有的链表中(如果链表不存在即运行该函数时头指针值为0,则该结点就赋值给链表类成员的头指针,作为链表中的唯一结点存在。
)由于一开始每一个结点都是由小到大插入的,所以该链表最终工资数据一定是按工资值的大小进行排序存放的。
链表类的增加工资记录的函数:
voidAddRecord()
{CNode*pnode;
CSalary*psal;
charname0[20];
doublesalary0;
cout<<"请输入姓名(按0结束):
";
cin>>name0;
while(strcmp(name0,"0"))
{cout<<"请输入工资:
";
cin>>salary0;
cin.ignore();
psal=newCSalary;
psal->SetSalary(name0,salary0);
pnode=newCNode;
pnode->InputDate(psal);
inlist(pnode);
cout<<"请输入姓名(按0结束):
";
cin>>name0;
}
cout< } 链表类的按照工资大小插入节点的函数 voidinlist(CNode*node0)//按照工资大小插入节点的类函数 {CNode*p0; if(phead==0) {phead=node0; n++; } else {CNode*p0,*p1; p0=phead; p1=phead->pnext; if(node0->pdata->getsalary()<=phead->pdata->getsalary()) {node0->pnext=phead; phead=node0; } else {for(inti=0;i<(n-1);i++) {if((node0->pdata->getsalary()>p0->pdata->getsalary())&&(node0->pdata->getsalary()<=p1->pdata->getsalary())) p0->pnext=node0,node0->pnext=p1; p0=p0->pnext,p1=p0->pnext; } if(node0->pdata->getsalary()>p0->pdata->getsalary()) p0->pnext=node0,node0->pnext=0; } n++; } } 2.显示工资记录。 主菜单中显示工资的功能会先调用链表类Clist的成员函数voidShowList(),该函数会通过循环语句,调用每一个结点对应的结点类函数voidShowNode()函数,调用结点对应数据类成员的数据类函数voidshow()把员工的姓名和工资数据打印在显示屏上。 链表类的打印工资记录的函数 voidShowList()//打印工资记录的类函数 {CNode*p1; p1=phead; inti=0; for(;i {p1->ShowNode(); p1=p1->pnext; } } 结点类的显示函数 voidShowNode(){pdata->show();} 数据类的显示函数 voidshow() {cout<<"姓名: "< "< } 3.根据姓名查询工资记录。 主菜单中根据姓名查询工资的功能是调用链表类的函数voidFindRecord()来实现,该函数通过循环语句查找所有节点,对每一节点会执行数据类的函数intcompare(charaa[]),该函数的功能是把字符串aa和类成员字符串name进行比较如果两个字符串相同会返回1,否则返回0,在比较的时候会把name和aa中所有字符转换为小写字母进行比较,以实现大小写通用的功能。 如果返回值为1时,链表类函数就会执行数据类函数的voidshow()函数,把该结点的工资记录打印出来,直至比较完所有结点。 所以该功能可以打印出链表中所有同名(大小写通用)的工资记录。 链表类的按照姓名查找工资记录的类函数: voidFindRecord()//按照姓名查找工资记录的类函数。 {cout<<"请输入要查找的姓名"< charcc[20]; cin>>cc; strlwr(cc); CNode*p1; p1=phead; inti=0,ss=0; for(;i {if(p1->pdata->compare(cc)) {p1->ShowNode(); ss++; } p1=p1->pnext; } if(ss==0) cout<<"未查找到该员工数据! "< else {cout<<"共查找到"< "; } } 数据类的比较函数: intcompare(charaa[]) {chardd[20]; strcpy(dd,name); strlwr(dd); intbb=strcmp(aa,dd); if(bb==0) bb=1; else bb=0; returnbb; } 4.根据姓名查找并删除工资记录。 主菜单中根据姓名查找并删除工资记录的功能是调用链表类中的函数voidDeleteRecord()实现的。 该函数在执行查询功能时与函数voidFindRecord()基本差不多也是大小写通用,但是为了方便删除结点,也是为了可以应付同名或者姓名大小写不同但是字母一样的情况出现(例如Mike,和mike),该函数建立了一个结点类的指针数组,每找到一个结点会把该结点的上一节点的指针保存在数组中(因为要更改上一结点的next指针,所以要保存上一指针),如果是头指针则把0赋给数组。 接着把查询结果都打印出来,由用户选择要删除哪个用户数据。 用户选择后会输出确认删除的语句,用户确认后开始删除。 如果数组成员为0,则修改头指针为下一结点,如果是正常指针则修改该指针指向的next指针为下下个结点指针。 链表类中按照姓名查找并删除工资记录的函数 voidDeleteRecord()//按照姓名查找并删除工资记录的类函数。 {cout<<"请输入要查找的姓名"< charcc[20]; cin>>cc; strlwr(cc); CNode*p1,*p0,*o[5]; p0=0; p1=phead; inti=0,ss=0; for(;i {if(p1->pdata->compare(cc)) {cout<<"第"< "; o[ss]=p0; p1->ShowNode(); ss++; } p0=p1; p1=p1->pnext; } if(ss==0) cout<<"未查找到该员工数据! "< else {cout<<"共查找到"< 要删除哪位员工的数据? "< intkk; CNode*p1; cin>>kk; kk=kk-1; if(o[kk]==0) cout<<"确定要将员工"< "< else cout<<"确定要将员工"< "< intll; cin>>ll; if(ll==1) {if(o[kk]==0) {CNode*p5; p5=phead; phead=phead->pnext; deletep5; n--; } else {CNode*p5; p5=o[kk]->pnext; p1=o[kk]->pnext->pnext; o[kk]->pnext=p1; n--; deletep5; } } else cout<<"操作取消返回主菜单! "< } } 4.根据姓名查找并删除工资记录。 主菜单中根据姓名查找并删除工资记录的功能是调用链表类的函数voidWriteRecord()来实现,该函数使用了voidDeleteRecord()的思想,采用同样的方式查找结点,也是大小写通用,并也定义了一个结点类指针数组,把查找到的符合条件的上一结点的指针保存在数组中,在查询完毕后,把所有找到的符合条件的结点打印出来,供用户选择删除哪个数据,在用户选择后,用户可以重新输入工资,输入后,会输出是否确认修改的语句,用户确认后再修改对应结点的数据类的工资数据。 因为修改后用户工资数据排序就会出问题,为了解决此办法接着会再新建一个结点与修改后结点相同,把链表里原来的结点删除,再运行函数voidinlist()按照工资大小插入结点! 链表类中按照姓名查找并修改工资记录的函数: voidWriteRecord()//按照姓名查找并修改工资记录的类函数。 {cout<<"请输入要查找的姓名"< charcc[20]; cin>>cc; strlwr(cc); CNode*p1,*o[5],*p0; p1=phead; p0=0; inti=0,ss=0; for(;i {if(p1->pdata->compare(cc)) {cout<<"第"< "; o[ss]=p0; p1->ShowNode(); ss++; } p0=p1; p1=p1->pnext; } if(ss==0) cout<<"未查找到该员工数据! "< else {cout<<"共查找到"< 要修改哪位员工的数据? "< intkk; cin>>kk; kk=kk-1; doublemm; cout<<"请输入修改后的工资: "; cin>>mm; cout< if(o[kk]==0) cout<<"确定要将员工"< "< "< else cout<<"确定要将员工"< "< "< intll; cin>>ll; if(ll==1) {if(o[kk]==0) {CNode*p5; p5=phead; phead=phead->pnext; n--; CNode*pp; CSalary*ppp; pp=newCNode; ppp=newCSalary; pp->pdata=ppp; ppp->SetSalary(p5->pdata->getname(),mm); inlist(pp); deletep5; } elseif(o[kk]->pnext->pnext! =0) {CNode*p5; p5=o[kk]->pnext; p1=o[kk]->pnext->pnext; o[kk]->pnext=p1; n--; CNode*pp; CSalary*ppp; pp=newCNode; ppp=newCSalary; pp->pdata=ppp; ppp->SetSalary(p5->pdata->getname(),mm); inlist(pp); deletep5; } else {CNode*p5; p5=o[kk]->pnext; o[kk]->pnext=0; n--; CNode*pp; CSalary*ppp; pp=newCNode; ppp=newCSalary; pp->pdata=ppp; ppp->SetSalary(p5->pdata->getname(),mm); inlist(pp); deletep5; } } else cout<<"操作取消返回主菜单! "< } }5.程序的文件输入输出功能。 在执行程序中首先将工资数据从文件中读出再进行管理,在程序结束时能将工资数据保存在原文件中。 该部分的功能也是通过俩个链表类的函数voidinfire0()和voidoutfire0()实现的。 在voidinfire0()函数中会先以二进制的模式打开文件,在把链表类的成员n(表示结点个数)写在(四个字节)文件的开头,再按照链表顺序把一个个结点对应的数据类的数据写入内存中,直到把n个结点写完。 内存写入文件的函数: voidoutfire0()//将内存中的链表内容转存到文件中的类函数 {ofstreamoutfire; outfire.open("aa.dat",ios: : out|ios: : binary); intbb; bb=n; outfire.write((char*)&bb,4); intk=0; CNode*p0; p0=phead; for(;k { outfire.write((char*)p0->pdata,sizeof(CSalary)); p0=p0->pnext; } } 而在函数voidinfire0()中对应着存储规则,会先以二进制的方式打开文档(如果文档不存在则打开失败并输出提示语句),再读取开头四个字节存入主函数中建立的链表类的n的地址,接着用一个循环语句执行一次循环语句就建立新的结点类和一个数据类成员,并把文档中接着的sizeof(CSalary)个字节读入到数据类中,把数据类的指针赋给结点类的成员pdata,修改pnxet,直至建立好n个结点,最终就利用文档中的数据建好了整个链表。 把文档中内容写入内存的函数: voidinfire0()//将文件中的数据读取出来到链表中 {ifstreaminfire; infire.open("aa.dat",ios: : binary|ios: : nocreate); if(! infire) {cout<<"未存在工资记录请添加记录"< } else {intbb; infire.read((char*)&bb,4); n=bb; CSalary*p1; CNode*p0; p0=newCNode; inti=0; for(;i {p1=newCSalary; infire.read((char*)p1,sizeof(CSalary)); p0->pdata=p1; p0->pnext=newCNode; if(i==0) phead=p0; p0=p0->pnext; } p0->pnext=0; } } }; 七.总结 整个程序都是我们利用已学的C++知识,参考着源程序编写的,在编写过程中难免会有些东西不会,例如文件的输入和输出,为了解决这个问题恶补了一下这方面的知识。 最后也成功地把这个问题解决了! 源程序中也有些语句看不懂,翻翻书,在网上查查,学会了很多c++的知识! 在编写这个程序中还学到了其他的东西,为了完成整个管理程序,我们把所有的功能的实现通通分解为一个个函数。 把整个大的问题分解为小问题,一个个问题分工合作完成,最终完成了这个程序! 能凭借自己的手完成这个程序,最后真的很有成就感,似乎明白了那些it男为什么面对着如此枯燥的代码还能津津有味的心境! 九.源程序代码 #include #include #include #include #include classCSalary//数据类 {private: charname[20];//姓名 doublesalary;//工资 public: CSalary(void){strcpy(name,"/0");salary=0.0;} CSalary(char*p,doubleaa) {strcpy(name,p); salary=aa; } voidSetSalary(char*p,doubleaa) {strcpy(name,p); salary=aa; } voidSetSalary(doubleaa) { salary=aa; } doublegetsalary() {returnsalary; } char*getname() {returnname; } intcompare(charaa[]) {chardd[20]; strcpy(dd,name); strlwr(dd); intbb=strcmp(aa,dd); if(bb==0) bb=1; else bb=0; returnbb; } voidshow() {cout<<"姓名: "< "< } }; classCNode//结点类 {CSalary*pdata; CNode*pnext; public: CNode(){pdata=0;pnext=0;} CNode(CNode&node) {pdata=node.pdata; pnext=node.pnext; } voidInputDate(CSalary*pSal){pdata=pSal;} voidShowNode(){pdata->show();} CSalary*GetDate(){returnpdata;} CNode*Getnext(){returnpnext;} friendclassClist; }; classClist//链表类 {protected: CNode*phead; intn; public: Clist(){phead=0;n=0;} ~Clist()//析构函数 {CNode*p1,*p2; CSalary*p3; p1=phead; p2=p1->pnext; p3=p1->pdata; for(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 南京理工大学C 课程设计工资管理 南京理工大学 课程设计 工资管理