工资管理课程设计报告.docx
- 文档编号:24212066
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:24
- 大小:94.80KB
工资管理课程设计报告.docx
《工资管理课程设计报告.docx》由会员分享,可在线阅读,更多相关《工资管理课程设计报告.docx(24页珍藏版)》请在冰豆网上搜索。
工资管理课程设计报告
南京理工大学VC++课程设计报告
课程:
VC++课程设计
系别:
班级:
选题2名称:
工资管理
选题2难易级别:
A级
自报成绩:
日期:
2012年10月19日
目录
一、课题目标
1-1程序功能简介
1-2课程设计要求
1-3评定难易级别
二、具体实现
2-1开发平台
2-2源程序主函数结构流程图
2-3基本类及主要函数
2-3-1基本类
2-3-1-1工资数据类
2-3-1-2结点类
2-3-1-3链表类
2-3-2主要函数
2-3-2-1数据的录入
2-3-2-2数据按姓名查找
2-3-2-3数据的显示
2-3-2-4删除链表
2-3-2-5插入新节点
2-3-2-6数据文件的存取
2-3-2-7增加数据
三、调试报告
(在设计和实现过程所遇到的问题和解决)
四、总体小结
(在整个设计过程中的心得体会)
五、分工介绍
(是独立完成还是合作完成)
一、课题目标
1-1:
程序功能简介:
这是一个员工工资管理程序。
工资管理的数据文件中存储有员工姓名和工资,该程序可以录入、显示、查找、修改、删除员工的姓名和工资。
1-2课程设计要求:
(1)用类的形式改写程序,将程序中工资数据用链表的形式存放,定义一个链表类,封装主要的操作函数。
(2)显示、修改、删除数据项时大小写通用。
(3)工资数据按照工资值的大小进行排序存放。
(4)修改,删除数据前增加提示信息,用户确认后才能进一步的修改及删除操作,否则取消操作。
(5)增加程序的文件输入输出功能,在执行程序中首先将工资数据从文件中读出来再进行管理,在程序结束时能将工资数据保存在原文件中。
1-3评定难易级别
A级
二、具体实现
2-1、开发平台
操作系统:
Windows7
开发工具VC++6.0
2-2、源程序主函数结构流程图
N
Y
Y
N
N
Y
0-
1
3
4-
5-
2
2-3、基本类及主要函数
2-3-1-1工资数据类
classSalary//定义一个工资的类,用于描述节点的数据信息
{
private:
charcName[20];//用于存放员工姓名
doubledSalary;//用于存放员工薪水数据
public:
Salary()//定义缺省的构造函数
{
strcpy(cName,"\0");
dSalary=0.0;
}
Salary(char*name,doublesalary)//定义有参数的构造函数
{
strlwr(name);
strcpy(cName,name);
dSalary=salary;
}
voidSetSalary(char*name,doublesalary);//置相关数据的值
char*GetName();//返回对象中员工名字
doubleGetSal();//返回对象中员工的薪水
intCompare(Salary&s);
voidShow()//输出数据
{
cout< "< } }; 2-3-1-2结点类 classNode//定义一个结点类 { private: Salary*pData;//描述结点的数据域 Node*pNext,*prew;//构成链表的前后向指针 public: Node()//缺省的构造函数,置结点的 { pData=0; pNext=prew=0; } Node(Node&node)//完成拷贝功能的拷贝构造函数 { pData=node.pData; pNext=node.pNext; prew=node.prew; } voidInputData(Salary*pSal)//使得结点的数据域指针指向某数据 voidShowNode()//展示结点数据 Salary*GetData()//返回指向结点的数据域的指针 voidSetData(Salary*p)//改变结点的数据域 Node*GetNext()//返回下一个结点的地址 voidSetNext(Node*p)//置结点中的向后指针 voidSetprew(Node*p)//置结点中的向前指针 friendclassList;//定义友元类 }; 2-3-1-3链表类 classList//定义链表类,实现双向链表操作 { protected: Node*pHead,*pTail;//链表首指针和链表尾指针 public: List(){pHead=NULL,pTail=NULL;}//缺省的构造函数,置首尾指针为NULL ~List(){DeleteList();}//析构函数 voidAddNode(Node*pnode)//增加一个节点,直接加在链首 voidDeleteNode(Node*p)//删除某结点 Node*LookUp(Salary&s)//在链表中搜索某个指定的结点 voidShowList()//按照从链表首到尾,输出链表数据成员 voidDeleteList()//删除链表 Node*GetListHead()//返回链表首指针 Node*GetListNextNode(Node*n)//返回指向下一个结点的指针 voidSetListHead(Node*p)//置结点头指针 intInsert(Node*p)//插入一个节点 intPrintList()//输出到文件 }; 主要功能及其实现函数 2-3-2-1数据的录入 voidSetSalary(char*name,doublesalary)//置姓名与工资的值 { strlwr(name); strcpy(cName,name); dSalary=salary; } char*GetName()//返回对象中员工名字 { returncName; } doubleGetSal()//返回对象中员工的薪水 { returndSalary; } intCompare(Salary&s) { if(strcmp(cName,s.cName)) { return0; } else { return1; } } voidShow()//输出数据 { cout<<"员工"< "< } }; 2-3-2-2数据按姓名查找 Node*LookUp(Salary&s)//在链表中搜索某个指定的结点 { Node*p1,*p2; if(pHead==NULL) {cout<<"~~~~(>_<)~~~~数据不存在! "< returnNULL; } if(pHead->pData->GetSal()==s.GetSal()) {returnpHead; } else { p2=p1=pHead; while(p2->pData->GetSal()! =s.GetSal()&&p2->pNext! =NULL) {p1=p2; p2=p2->pNext; } if(p2->pData->GetSal()==s.GetSal()) {returnp2; } else { cout<<"没有找到相应数据! "< returnNULL; } } } 2-3-2-3数据的显示 voidShowList()//按照从链表首到尾,输出链表数据成员 { cout<<"***************************"< Node*p=pHead; while(p! =NULL) { p->ShowNode(); p=p->pNext; } cout< cout<<"***************************"< cout< } 2-3-2-4删除链表 voidDeleteList()//删除链表 { Node*p; while(pHead! =NULL) { p=pHead; pHead=pHead->pNext; deletep; } } 2-3-2-5插入新节点 intInsert(Node*p)//插入一个结点 { Node*p1,*p2; if(pHead==NULL)//条件成立时,为空链表 { p->pNext=NULL; p->prew=NULL; pHead=p;//使链首和链尾指针指向该结点 pTail=p; return0; } if(pHead->pData->GetSal()>=p->pData->GetSal())//第一个数大于新插入数,直接插到头结点 { pHead->prew=p; p->pNext=pHead; p->prew=NULL; pHead=p;//直接将该结点加入链首,并改变链首的指针值 return0; } p1=p2=pHead; while(p2->pNext&&p2->pData->GetSal() { p1=p2; p2=p2->pNext; } if(p2->pData->GetSal() { p->prew=p2; p2->pNext=p; p->pNext=NULL; pTail=p;//直接将该结点加在链尾 } else//"else"代表该结点应该插入链表中间的某个位置 { p2->prew=p; p->pNext=p2; p->prew=p1; p1->pNext=p; } return0; } 2-3-2-6数据文件的存取 intPrintList() { charfilename[255]; cin.ignore(); cin.getline(filename,254); ofstreamoutfile(filename);//以写方式打开filename的文件 if(! outfile)//判断是否打开成功 { cout<<"打开源文件失败,不能打开源文件。 "< return0; } Node*p=pHead; while(p! =NULL)//判断是否已经到达链尾,将链表上的数据输入到文件中 { outfile< outfile< p=p->GetNext(); } outfile.close();//关闭文件 return0; } intGetList()//从文件中输出(无论初次文件中的数据是否有顺序) { charfilename[255]; cout<<"请输入文件名: "< Node*p=0; Salary*s; cin.ignore(); cin.getline(filename,254); ifstreaminfile(filename,ios: : in);//以读方式打开文件filename if(! infile)//判断是否打开成功 { cout<<"不能打开源文件."< return0; } charname[20],ch; doublesal; p=newNode; s=newSalary; pHead=pTail=NULL; while(infile.getline(name,20))//判断是否已经取完数据,满足条件则进行循环 { infile>>sal; s->SetSalary(name,sal); p->SetData(s); Insert(p); infile.get(ch);//读取文件流中的一个换行符 p=newNode; s=newSalary; } deletep; deletes; infile.close(); cout<<"读取文件成功! "< cout< return0; } voidDeleteFirNode() { Node*p=pHead; pHead=pHead->GetNext(); deletep; } }; 2-3-2-7增加数据 voidAddRecord(List&SalaryList)//增加某结点,即增加工资记录 { Node*pNode; Node*p1,*p2; Salary*pSal; charcName[20]; charstr[100]; doubledPlaceSalary; cout<<"请输入姓名(输入0结束): "; cin.ignore(); cin.getline(cName,20); while(strcmp(cName,"0"))//判断是否结束增加 { charflag1; pNode=newNode; pSal=newSalary; pSal->SetSalary(cName,0); Node*hd; hd=SalaryList.GetListHead();//将hd指向链表 if(hd==NULL)//判断链表是否为空 { cout<<"请输入工资: "; cin>>dPlaceSalary; while(! cin)//判断是否输入成功 { cin.clear();//重置状态字state中的二进制位 cin.getline(str,100);//将流中的错误数据清除 cout<<"非法输入,请输入正确工资数据: "< cin>>dPlaceSalary; } pSal->SetSalary(cName,dPlaceSalary);//将psal指向的对象设置数据 pNode->InputData(pSal);//置结点的数据域 SalaryList.Insert(pNode);//将结点插入到链表中 cout<<"请输入姓名(输入0结束): "; cin.ignore(); cin.getline(cName,20); continue;//结束本轮循环,直接进行判断进入下一轮的循环 } if(hd->GetData()->Compare(*pSal))//判断增加的结点的名称是否存在(此次判断是是否存在于链首) { cout<<"您输入的名字数据库中已存在,是否重新输入其工资数据? 选Y或y为是,其它任意键为否"< cin>>flag1; if((flag1=='y')||(flag1=='Y')) { cout<<"请输入工资: "; cin>>dPlaceSalary; while(! cin) { cin.clear(); cin.getline(str,100); cout<<"非法输入,请输入正确工资数据: "< cin>>dPlaceSalary; } hd->GetData()->SetSalary(cName,dPlaceSalary); cout<<"请输入姓名(输入0结束): "; cin.ignore(); cin.getline(cName,20); } else { cout<<"请输入姓名(输入0结束): "; cin.ignore(); cin.getline(cName,20); } } else { p2=p1=hd; while(p2->GetData()->Compare(*pSal)==0&&p2->GetNext()! =NULL)//搜索链表中是否有与其姓名一样的数据 { p1=p2; p2=p2->GetNext(); } if(p2->GetData()->Compare(*pSal))//判断在增加的数据的姓名是否已经存在,满足条件则存在 { cout<<"您输入的名字数据库中已存在,是否重新输入其工资数据? 选Y或y为是,其它任意键为否"< cin>>flag1; if((flag1=='y')|(flag1=='Y')) { cout<<"请输入工资: "; cin>>dPlaceSalary; while(! cin) { cin.clear(); cin.getline(str,80); cout<<"非法输入,请输入正确工资数据: "< cin>>dPlaceSalary; } p2->GetData()->SetSalary(cName,dPlaceSalary); } cout<<"请输入姓名(输入0结束): "; cin.ignore(); cin.getline(cName,20); } else//else说明输入的数据的名称在链表中不存在 { cout<<"请输入工资: "; cin>>dPlaceSalary; while(! cin) { cin.clear(); cin.getline(str,80); cout<<"非法输入,请输入正确工资数据: "< cin>>dPlaceSalary; } pSal->SetSalary(cName,dPlaceSalary); pNode->InputData(pSal); SalaryList.Insert(pNode); cout<<"请输入姓名(输入0结束): "; cin.ignore(); cin.getline(cName,20); } } } cout< } 三、调试报告 问题1: 显示、修改、删除数据时,大小写通用问题 解决方法: 所有从文件(磁盘文件与外设文件)中读取的数据都先经过strlwr(char*)的处理,才会进入链表中,输出数据时都以小写输出。 问题2: 在选择删除时,一定会显示工资最低的人的信息 经检验,由于某次输入时光标位置错误,导致代码输错行,此次充分体现了细心的重要性。 问题3: 需要读取的文件中的数据不是按照一定的从小到大(或从大到小)排列,读取文件时如何建立有序链表。 解决方法: 每一个数据读入时,都按照插入链表的形式加入到链表中,而非简单的接在链尾,这样原文件中无序的数据读入链表时,就已经是有序的了。 问题4: 打开关闭文件时有错误: 一开始发现在开始欢迎界面上,选择打开已有链表后,就算输入不存在的文件名,都提示“读取文件成功” 解决方法: 因为刚刚学的文件操作,不是很熟悉,在研究了课本后发现问题出在这里ifstreaminfile(filename,ios: : in);这里缺少一个只能打开已存在文件的限定,将其改为 ifstreaminfile(filename,ios: : in|ios: : nocreate);后问题解决了。 四、总体小结 不要一味追求速度,在追求编写速度提高的同时,出现错误的可能性也大大提高,而编写时节省下来的时间远远比不上改错用的时间;书写要尽量清晰,加注解很重要,方便阅读和找出错误;方法很重要,能帮助减少书写量,程序运行效率也更高;注意细节,对临界值确定一定要小心,很可能出现错误。 为了及时找出错误,我将写的初级版程序打印出来,方便熟悉它以及更多思考它的不足。 事实证明,大量的心力投入是程序较完善的重要前提。 由此我懂得了,做任何事,只要付出不是百分之百,那么后果多将有可能是我们所不能承受的。 因此在以后的日子里,我在做事时都将更认真,更投入。 五分工介绍 独立完成
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 工资管理 课程设计 报告