Visual C++ 课程设计报告 ——————工资管理
一 程序功能简介
这是一个员工工资管理程序。工资管理程序的数据文件中存储有员工姓名和工资,该程序可以录入、显示、修改、删除、查找员工姓名和工资。
二课程设计心得
因为以前课上讲的类都是很简单的类的运用,并没有涉及完全通过类的调用来建立链表,所以遇到了不少问题: 1,
起初并不知道如何用类来建立链表。也完全不理解cnode类的
作用,以为完全可以用cllist来调用完成。 2,
设计过程中,一开始不明白gethead,以及其他这样类中返回
节点,返回数据的作用。所以并没有设立这些函数,很久之后调试出现问题,才想起最基本的类外函数不可以直接调用私有成员。 3,
由于输入输出流,老师上课讲的不多,一开始找不到文件输入
输出的方法。后来通过模仿书上的输入方式,及与做同一课题的同学进行了交流解决了这个问题。 4,
程序编完后出现第一个解决不了的问题是输入,总是没显示,
找了很久才发现是因为函数都是在传值,加了引用才解决。但后来又出现了问题,地址重复,想了很久通过在函数中再设一个同类变量解决。还有一个问题便是一开始不管怎么输出都只能输出
一行后来发现是因为在addrecord函数中p未付新空间
通过解决这么多问题,在查书和与同学商讨中一步一步的深入了对类和链表的认识。并学会了怎样在错误中一步步吸取教训,达到正确目标。 不足之处:
1 界面不太友好。多次操作时因为重复显示菜单界面有点混乱。 2 程序有点冗长。有的地方可以简化一点
三 课程设计的要求,及自己的解决方法
(1)用类的形式改写程序。
该程序中共定义了3个类。
第一个为数据类,是用来存储员工姓名和工资数据的类。具体内容如下: class CSalary {
char szname[20]; double dlSalary;
//姓名
//工资
public:
dlSalary=0.0;} //默认构造函数
CSalary() {strcpy(szname,\"\\0\");
CSalary(char *,double);
//构造函数
void SetSalary(char a[],double s) {dlSalary=s; strcpy(szname,a);
} //工资与姓名输入 char *GetName() {return szname;} double GetSal()
{return dlSalary;} //返回工资 int Compare(char name[]) {if(strcmp(name,szname)==0) return 1; else }
return 0;
//比较姓名,供查找用,比较结果1,0
//返回姓名
void Show() {cout<<\"
姓
名
\"< 工 资 =\"< }; 第二个为结点类,该类涉及结点的输入、输出、复制等。具体如下: cclass CNode { //定义结点类 {dlSalary=a;} CSalary *pData; //用于指向数据类的指针,这是 每个数据的不同部分 CNode *pNext; //指向链表的指针 public: CNode() { pData=0; pNext=0; } //结点的构造函数 CNode(CNode &node) { pData=node.pData; pNext=node.pNext; } //用于拷贝的构造函数 //输入 void InputData(CSalary *pdata) {pData=pdata;pNext=0;} 数据 void ShowNode() {pData->Show();} //显示数据 CSalary *GetData() { return pData;} CNode *Getnext(){return pNext;} //返回下 一个节点 }; friend class CList; //定义友元类 第三个类为链表类,将结点视为类中的数据成员,涉及结点的插入、输出、删除等操作。具体如下: class CList { protected: CNode *pHead; public: CList() {pHead=0;} // 默认构造函数 void DeleteList(); // 删除整个链表 ~CList(){DeleteList();} // 解析函数 void DeleteNode(CNode *); //删除一个指定的结点,返 回该结点的指针 CNode *LookUp(char name[20]); void ShowList(); //输出整个链表 //返回链表首 CNode *GetListHead() {return pHead; } 结点 }; void Insert(CNode *); //按工资的顺序插入一个结点 //返回链表的最后一个结点 CNode *GetLastNode(); (2)显示、修改、删除数据时大小写通: 定义了一个函数,通过调用库函数strupr,全部转化成大写。 void change(char p[]) {strcpy(p,strupr(p));} (3)工资数据按工资值的大小进行排序存放: 编写insert函数时,便设置了从小到大的顺序进行插入 void CList::Insert(CNode *p0) //按工资的顺序插入一个结点 { CNode *p,*q; if(pHead==0) { pHead=p0; pHead->pNext=0; return; } p=pHead; while(p0->pData->GetSal()>p->pData->GetSal()&&p->pNext!=0) { q=p; p=p->pNext; } if(p0->pData->GetSal()<=p->pData->GetSal()) {if(p==pHead) {p0->pNext=pHead; pHead=p0; } else {p0->pNext=p; q->pNext=p0; } } else {p->pNext=p0; p0->pNext=0; } return; } (4)修改、删除数据前增加提示信息,用户确认后才能进一步操作, 否则操作取消。 用if语句进行控制 {cout<<\"请确认是否执行删除操作,继续 Y否则N\\n\"; char name[20]; char a; cin>>a; if (a=='N'||a=='n') return; else if(a=='Y'||a=='y') {cout<<\"请输入查询姓名\\n\"; cin>>name; change(name); CNode *p=list.LookUp(name); if(p) list.DeleteNode(p); else cout<<\"未找到查询姓名\\n\"; return; } else cout<<\"操作无效,请重新输入操作\\n\"; return; } (5)增加程序的文件输入输出功能,在执行程序中首先将工资数据从文件中读出再进行管理,在程序结束时能将工资数据保存在原文件中 定义了input1和save两个类外函数 void save(CList &list) { ofstream outfile(\"data.txt\"); char name[20]; double salary; CNode *p=list.GetListHead(); while(p) { strcpy(name,p->GetData()->GetName()); salary=p->GetData()->GetSal(); outfile< void input1(CList &list) { } ifstream infile(\"data.txt\"); char name[20]; double salary; while(!infile.eof()) { infile>>name>>salary; CSalary *psalary=new CSalary; psalary->SetSalary(name,salary); CNode *pnode=new CNode; pnode->InputData(psalary); list.Insert(pnode); } 四 源程序代码 #include char szname[20]; //姓名 double dlSalary; //工资 public: CSalary() {strcpy(szname,\"\\0\"); dlSalary=0.0;} //默认构造函数 CSalary(char *,double); //构造函数 void SetSalary(char a[],double s) {dlSalary=s; strcpy(szname,a); } //工资与姓名输入 char *GetName() {return szname;} //返回姓名 double GetSal() {return dlSalary;} //返回工资 int Compare(char name[]) {if(strcmp(name,szname)==0) return 1; else return 0; } //比较姓名,供查找用,比较结果1,0 void Show() {cout<<\"姓名\"< class CNode //定义结点类 { CSalary *pData; //用于指向数据类的指针,这是每个数据的不同部分 CNode *pNext; //指向链表的指针 public: CNode() { pData=0; pNext=0; } //结点的构造函数 CNode(CNode &node) { pData=node.pData; pNext=node.pNext; } //用于拷贝的构造函数 void InputData(CSalary *pdata) {pData=pdata;pNext=0;} //输入数据 void ShowNode() {pData->Show();} //显示数据 CSalary *GetData() { return pData;} CNode *Getnext(){return pNext;} //返回下一个节点 friend class CList; //定义友元类 }; class CList { protected: CNode *pHead; public: CList() {pHead=0;} // 默认构造函数 void DeleteList(); // 删除整个链表 ~CList(){DeleteList();} // 解析函数 void DeleteNode(CNode *); //删除一个指定的结点,返回该结点的指针 CNode *LookUp(char name[20]); void ShowList(); //输出整个链表 CNode *GetListHead() {return pHead; } //返回链表首 结点 void Insert(CNode *); //按工资的顺序插入一个结点 CNode *GetLastNode(); //返回链表的最后一个结点 }; void CList::DeleteList() //删除整个链表 { if(pHead==0)return; CNode *p,*q; p=pHead; while(p) { delete p->pData; q=p; p=p->pNext; delete q; } pHead=0; } CNode *CList::LookUp(char name[20]) { if(pHead==0) return 0; CNode *p1=pHead; while(p1) { if(p1->pData->Compare(name)==0) return p1; p1=p1->pNext; } return 0; } void CList::ShowList() //打印整个链表 { if(!pHead) { cout<<\"没有纪录!\"< { p->ShowNode(); p=p->pNext; } } void CList::Insert(CNode *p0) //按工资的顺序插入一个结点 { CNode *p,*q; if(pHead==0) { pHead=p0; pHead->pNext=0; return; } p=pHead; while(p0->pData->GetSal()>p->pData->GetSal()&&p->pNext!=0) { q=p; p=p->pNext; } if(p0->pData->GetSal()<=p->pData->GetSal()) {if(p==pHead) {p0->pNext=pHead; pHead=p0; } else {p0->pNext=p; q->pNext=p0; } } else {p->pNext=p0; p0->pNext=0; } return; } void CList::DeleteNode(CNode *pnode) { if(pnode==pHead&&pHead->pNext==0) { delete pHead->pData; delete pHead; pHead=0; } else if(pnode==pHead) { CNode *p=pnode->pNext; delete pHead->pData; delete pHead; pHead=p; } else { CNode *p=pHead; while(p&&p->pNext!=pnode) p=p->pNext; CNode *q=pnode->pNext; delete pnode->pData; delete pnode; p->pNext=q; } } void change(char p[]) // {strcpy(p,strupr(p));} void addrecord(CList &salary) //{CNode *p; CSalary *psal; char name[20]; double s; cout<<\"输入姓名(输入0结束):\\n\"; cin>>name; change(name); while(strcmp(name,\"0\")) {cout<<\"请输入工资\\n\"; cin>>s; psal=new CSalary; psal->SetSalary(name, s); p=new CNode; p->InputData(psal); salary.Insert(p); cout<<\"输入姓名(输入0结束):\"; cin>>name; change(name); } cout< 转换大小写 添加数据 {list.ShowList(); } void enquirerecord(CList &list) //查询数据 {cout<<\"请输入查询姓名\\n\"; char name[20]; cin>>name; change(name); CNode *p=list.LookUp(name); if (p) p->ShowNode(); else cout<<\"未找到查询姓名,请重新输入操作\\n\\n\\n\"; return; } void deleterecord(CList &list) //删除数据 {cout<<\"请确认是否执行删除操作,继续 Y否则N\\n\"; char name[20]; char a; cin>>a; if (a=='N'||a=='n') return; else if(a=='Y'||a=='y') {cout<<\"请输入查询姓名\\n\"; cin>>name; change(name); CNode *p=list.LookUp(name); if(p) list.DeleteNode(p); else cout<<\"未找到查询姓名,请重新输入操作\\n\\n\\n\"; return; } else cout<<\"操作无效,请重新输入操作\\n\\n\\n\"; return; } void modifyrecord(CList &list) //修改数据 {cout<<\"请确认是否执行修改操作,继续 Y否则N\\n\"; char a; cin>>a; char name[20]; double dlsalary; if (a=='N'||a=='n') list.GetListHead(); else if(a=='Y'||a=='y') {cout<<\"请输入姓名\\n\"; cin>>name; change(name); CNode *p=list.LookUp(name); if(p!=0) {cout<<\"请输入修改值\\n\"; cin>>dlsalary; p->GetData()->ch(dlsalary); } else cout<<\"未找到查询姓名,请重新输入操作\\n\\n\"; return; } else cout<<\"操作无效,请重新输入操作\\n\"; return; } void save(CList &list) //文件存入 { ofstream outfile(\"data.txt\"); char name[20]; double salary; CNode *p=list.GetListHead(); while(p) { strcpy(name,p->GetData()->GetName()); salary=p->GetData()->GetSal(); outfile< void input1(CList &list) //文件导入 { CList a=list; ifstream infile(\"data.txt\"); 因篇幅问题不能全部显示,请点此查看更多更全内容