一、设计题目
1.设计目的
全面系统的学习面向对象程序设计的基本概念、基本语法和编程方法。正确理解掌握C++面向对象程序设计的基本特性:类、对象、继承与派生、多态、虚函数、模板、流类库等。遵循软件过程的各个环节进行系统分析、设计、实现、集成、测试。了解当前常用的软件开发工具,要求熟练掌握基于类的程序设计,培养解决实际问题的能力。
2.题目背景:人事管理系统
程序应采用面向对象的程序设计方法,程序应提供人员信息的输入、删除、查找、修改等基本功能,并且能够按部门进行各项分类统计,对各部门进行排序和筛选等操作。
在本程序中,人事管理系统将人员分为两个部门,每个部门均有添加员工、删除员工、修改员工信息、按照工资多少排序输出、按照工资多少筛选员工、按编号查找员工、写入和读取文件的功能。设置人事部为基类,员工信息有编号、姓名、工资;销售部为派生类,员工信息除了编号、姓名、工资,还加入了新的信息:奖金。因此在主函数下选择部门时,应用了虚函数,体现了多态性;在每步改动人员信息之后均会写入进文件,在打开程序时会自动读取文件。
二、需求分析
1.功能结构图
2.设计流程图
(1)添加员工 Add_member()
首先输入要添加的员工人数n(若n超出了可添加的范围,则返回重新输入),进入for循环,在总数total之后(total初值默认为0)循环n次,依次添加n个员工的编号、姓名、工资(销售部还包括奖金),每次total的值增加1。在输入编号时,通过for循环首先遍历已存在的total个员工的编号,若存在编号与刚刚录入的编号相等,则提示已有该编号,返回重新输入。
每次输入某员工信息完成后,文件指针从开头移动total个员工信息单位的长度,将信息写入到文件尾。
(2)删除员工 Delete_member()
输入要删除的员工的编号,通过for循环遍历total个员工的数据,若第i 个员工与其编号相等,则将该员工数据删除(删除方法:使用for循环,从i开始,用第i+1个员工的数据覆盖掉第i个员工的数据,以此类推,之后的员工数据都往前移动一位),total的值减去1;若遍历后没有找到该编号,则输出无此员工。
利用ios::out方式打开文件,即打开后清空数据。在删除该员工数据后,通过for循环重新从头开始写入每个员工的数据。
(3)修改员工信息 Change_member()
输入要修改的员工的编号,通过for循环遍历total个员工的数据,若第i 个员工与其编号相等,则首先输出该员工信息做参考,之后重新输入该员工数据;若遍历后没有找到该编号,则输出无此员工。
重新输入第i个员工的数据后,将文件指针从开头移动i个员工信息单位的长度,将修改后的该员工信息写入文件。
(4)按工资排序输出 Sort_by_wage()
通过for循环,将员工数据复制进新的结构体数组,用冒泡排序(从第total个员工开始,将其与前一个员工的工资进行比较,若大于则相互交换;total轮循环后,工资数最大的员工在第一个;再比较当前的第total个员工与total-1个员工,total-1轮循环后,工资数第二的员工在第二个……以此类推)按照工资(销售部是工资+奖金)的值的大小排序完成,最后用for循环从新的数组中输出排序好的员工信息。
(5)按工资筛选员工 Screen_by_wage()
定义统计人数的变量k,k初始化为0;输入筛选的起始点a和终止点b(若输入的b比a要小,返回重新输入),用for循环遍历total个员工数据,若员工工资的值在a ~ b范围内,输出该员工的数据,k+1;如果循环结束后k=0,即没有任何员工的工资的值在a ~ b范围内,则输出无该工资区间的员工。
(6)按编号查找员工 LookUp_by_number()
定义统计人数的变量k,k初始化为0;输入要查找的员工的编号,用for循环遍历total个员工的数据,若找到与其相等的编号,则输出该员工信息,k+1,终止循环;若遍历结束后k=0,即没有找到该编号,则输出无此员工。
完整代码
//2019-2020学年第一学期 面向对象程序设计综合实训(C++)
#include<iostream>
#include<iomanip>
#include<string>
#include<fstream>
using namespace std;struct Member//员工信息
{char number[20];//员工编号char name[20];//员工姓名double wage;//工资
}; class Base//人事部
{protected:Member member[20];//员工信息int total;//总人数 public:Base(){total=0;}virtual void Add_member();//添加员工 virtual void Delete_member();//删除员工 virtual void Change_member();//修改员工信息virtual void Sort_by_wage(); //按工资排序 virtual void Screen_by_wage(); //按工资筛选 virtual void LookUp_by_number(); //按编号查找 void Outfile_Base();//写入文件 void Infile_Base();//读取文件
}; class Department1:public Base //销售部
{private:double bonus[20];//奖金public:Department1(){total=0;}void Add_member();//添加员工void Delete_member();//删除员工void Change_member();//修改员工信息void Sort_by_wage();//按工资+奖金排序 void Screen_by_wage();//按工资+奖金筛选void LookUp_by_number(); //按编号查找 void Outfile_Department();//写入文件 void Infile_Department();//读取文件
}; void Base::Add_member()
{int n,i,j,w; w=total;cout<<"请输入将要添加的员工人数:";leap11:cin>>n;if(n>20-total){cout<<"添加人数超出可记录范围(20个),请重新输入:";goto leap11; }fstream iofile("information_base.dat",ios::in|ios::out|ios::binary);if(!iofile) cerr<<"文件打开失败!"<<endl; for(i=w;i<w+n;i++){cout<<"请输入员工编号:";leap12:cin>>member[i].number;for(j=0;j<w;j++){if(strcmp(member[i].number,member[j].number)==0){cout<<"已有该编号员工!请重新输入:";goto leap12;} }cout<<"请输入员工姓名:";cin>>member[i].name;cout<<"请输入该员工工资:";cin>>member[i].wage; iofile.seekp(i*sizeof(member[i]),ios::beg);iofile.write((char*)&member[i],sizeof(member[i]));cout<<"文件写入成功!"<<endl;iofile.close();total++; }cout<<"添加完成!"<<endl;
} void Base::Delete_member()
{int i,j,w,k=0;w=total;char n[20]; cout<<"请输入将要删除的员工的编号:"; cin>>n; fstream iofile("information_base.dat",ios::out|ios::binary);if(!iofile) cerr<<"文件打开失败!"<<endl; for(i=0;i<w;i++){if(strcmp(n,member[i].number)==0){for(j=i+1;j<w;j++){member[j-1]=member[j]; } total--;k++;break; } } iofile.seekp(i*sizeof(member[i]),ios::beg);for(j=0;j<w-1;j++){iofile.write((char*)&member[j],sizeof(member[j]));} cout<<"文件写入成功!"<<endl;iofile.close();if(k==0) cout<<"无此编号员工!"; else cout<<"删除完成!"<<endl;
} void Base::Change_member()
{int i,t,k=0;t=total;char n[20]; cout<<"请输入将要修改的员工的编号:"; cin>>n; fstream iofile("information_base.dat",ios::in|ios::out|ios::binary);if(!iofile) cerr<<"文件打开失败!"<<endl;for(i=0;i<t;i++){if(strcmp(n,member[i].number)==0){cout<<"当前员工姓名:"<<member[i].name<<" 工资:"<<member[i].wage<<endl; cout<<"请输入修改后员工姓名:";cin>>member[i].name;cout<<"请输入修改后该员工工资:";cin>>member[i].wage;iofile.seekp(i*sizeof(member[i]),ios::beg);iofile.write((char*)&member[i],sizeof(member[i]));cout<<"文件写入成功!"<<endl;iofile.close();k++;break; } } if(k==0) cout<<"无此编号员工!";else cout<<"修改完成!"<<endl;
} void Base::Sort_by_wage()
{int i,j;Member t;Member mem2[20];for(i=0;i<total;i++) mem2[i]=member[i]; for(i=0;i<total;i++){for(j=total-1;j>i;j--){if(mem2[j].wage<mem2[j-1].wage){t=mem2[j];mem2[j]=mem2[j-1];mem2[j-1]=t;}}} cout<<"***************************************************************"<<endl;for(i=total-1;i>=0;i--){cout<<"员工编号:"<<mem2[i].number<<setw(15)<<"员工姓名:"<<mem2[i].name<<setw(15)<<"工资:"<<mem2[i].wage<<endl;}cout<<"***************************************************************"<<endl;
}void Base::Screen_by_wage()
{int i,k=0;double a,b;cout<<"请输入工资区域起始点(最小值):";cin>>a;cout<<"请输入工资区域截止点(最大值):";leap51:cin>>b;if(b<a){cout<<"输入有误,请输入比起始点大的数字:";goto leap51;}cout<<"***************************************************************"<<endl;for(i=0;i<total;i++){if(member[i].wage>=a&&member[i].wage<=b){k++;cout<<"员工编号:"<<member[i].number<<setw(15)<<"员工姓名:"<<member[i].name<<setw(15)<<"工资:"<<member[i].wage<<endl;}}if(k==0) cout<<"无该工资区间的员工!"<<endl;cout<<"***************************************************************"<<endl;
}void Base::LookUp_by_number()
{int i,k=0;char n[20]; cout<<"请输入将要查找的员工的编号:"; cin>>n; for(i=0;i<total;i++){if(strcmp(n,member[i].number)==0){k++;cout<<"当前员工姓名:"<<member[i].name<<" 工资:"<<member[i].wage<<endl;break; } } if(k==0) cout<<"无此编号的员工!"<<endl;
} void Base::Outfile_Base()
{ofstream outfile("information_base.dat",ios::binary);if(!outfile) cerr<<"文件写入错误,请重试!"<<endl; else{ for(int i=0;i<total;i++){outfile.write((char*)&member[i],sizeof(member[i]));} outfile.close();cout<<"文件写入成功!"<<endl; }
}void Base::Infile_Base()
{int i=0;ifstream infile("information_base.dat",ios::binary);if(!infile) cerr<<"文件读取错误,请重试!"<<endl; else{while(infile.peek()!=EOF){ad((char*)&member[i],sizeof(member[i]));i++;total++;}infile.close(); cout<<"文件读取成功!当前人事部有"<<total<<"个员工的数据,"; }
}void Department1::Add_member()
{int n,i,j,w; w=total;cout<<"请输入将要添加的员工人数:";leap13:cin>>n;if(n>20-total){cout<<"添加人数超出可记录范围(20个),请重新输入:";goto leap13; }fstream iofile("information_department.dat",ios::in|ios::out|ios::binary);if(!iofile) cerr<<"文件打开失败!"<<endl; for(i=w;i<w+n;i++){cout<<"请输入员工编号:";leap14:cin>>member[i].number;for(j=0;j<w;j++){if(strcmp(member[i].number,member[j].number)==0){cout<<"已有该编号员工!请重新输入:";goto leap14;} }cout<<"请输入员工姓名:";cin>>member[i].name;cout<<"请输入该员工工资:";cin>>member[i].wage; cout<<"请输入该员工奖金:";cin>>bonus[i]; iofile.seekp(i*(sizeof(member[i])+sizeof(bonus[i])),ios::beg);iofile.write((char*)&member[i],sizeof(member[i]));iofile.write((char*)&bonus[i],sizeof(bonus[i]));cout<<"文件写入成功!"<<endl;iofile.close();total++; }cout<<"添加完成!"<<endl;
} void Department1::Delete_member()
{int i,j,w,k=0;w=total;char n[20]; cout<<"请输入将要删除的员工的编号:"; cin>>n; fstream iofile("information_department.dat",ios::out|ios::binary);if(!iofile) cerr<<"文件打开失败!"<<endl; for(i=0;i<w;i++){if(strcmp(n,member[i].number)==0){for(j=i+1;j<w;j++){member[j-1]=member[j];bonus[j-1]=bonus[j]; } total--;k++;break; } } iofile.seekp(i*(sizeof(member[i])+sizeof(bonus[i])),ios::beg);for(j=0;j<w-1;j++){iofile.write((char*)&member[j],sizeof(member[j]));iofile.write((char*)&bonus[j],sizeof(bonus[j]));} cout<<"文件写入成功!"<<endl;iofile.close();if(k==0) cout<<"无此编号员工!";else cout<<"删除完成!"<<endl;
} void Department1::Change_member()
{int i,k=0;char n[20]; cout<<"请输入将要修改的员工的编号:"; cin>>n; fstream iofile("information_department.dat",ios::in|ios::out|ios::binary);if(!iofile) cerr<<"文件打开失败!"<<endl; for(i=0;i<total;i++){if(strcmp(n,member[i].number)==0){cout<<"当前员工姓名:"<<member[i].name<<" 工资:"<<member[i].wage<<" 奖金:"<<bonus[i]<<endl; cout<<"请输入修改后员工姓名:";cin>>member[i].name;cout<<"请输入修改后该员工工资:";cin>>member[i].wage;cout<<"请输入修改后该员工奖金:";cin>>bonus[i]; iofile.seekp(i*(sizeof(member[i])+sizeof(bonus[i])),ios::beg);iofile.write((char*)&member[i],sizeof(member[i]));iofile.write((char*)&bonus[i],sizeof(bonus[i]));cout<<"文件写入成功!"<<endl;k++;break; } } if(k==0) cout<<"无此编号员工!";else cout<<"修改完成!"<<endl;
} void Department1::Sort_by_wage()
{int i,j;Member t1;Member mem2[20];double t2;double bou2[20];for(i=0;i<total;i++){mem2[i]=member[i];bou2[i]=bonus[i];}for(i=0;i<total;i++){for(j=total-1;j>i;j--){if(mem2[j].wage+bou2[j]<mem2[j-1].wage+bou2[j-1]){t1=mem2[j];mem2[j]=mem2[j-1];mem2[j-1]=t1;t2=bou2[j];bou2[j]=bou2[j-1];bou2[j-1]=t2;}}} cout<<"***************************************************************"<<endl;for(i=total-1;i>=0;i--){cout<<"员工编号:"<<mem2[i].number<<setw(15)<<"员工姓名:"<<mem2[i].name<<setw(15)<<"工资:"<<mem2[i].wage<<setw(15)<<"奖金:"<<bou2[i]<<endl;}cout<<"***************************************************************"<<endl;
}void Department1::Screen_by_wage()
{int i,k=0;double a,b;cout<<"请输入工资+奖金区域起始点(最小值):";cin>>a;cout<<"请输入工资+奖金区域截止点(最大值):";leap52:cin>>b;if(b<a){cout<<"输入有误,请输入比起始点大的数字:";goto leap52;}cout<<"***************************************************************"<<endl;for(i=0;i<total;i++){if(member[i].wage+bonus[i]>a&&member[i].wage+bonus[i]<b){k++;cout<<"员工编号:"<<member[i].number<<setw(15)<<"员工姓名:"<<member[i].name<<setw(15)<<"工资:"<<member[i].wage<<setw(15)<<"奖金:"<<bonus[i]<<endl;}}if(k==0) cout<<"无该工资+奖金区间的员工!"<<endl;cout<<"***************************************************************"<<endl;
}void Department1::LookUp_by_number()
{int i,k=0;char n[20]; cout<<"请输入将要查找的员工的编号:"; cin>>n; for(i=0;i<total;i++){if(strcmp(n,member[i].number)==0){k++;cout<<"当前员工姓名:"<<member[i].name<<" 工资:"<<member[i].wage<<" 奖金:"<<bonus[i]<<endl;break; } } if(k==0) cout<<"无此编号的员工!"<<endl;
} void Department1::Outfile_Department()
{ofstream outfile("information_department.dat",ios::binary);if(!outfile) cerr<<"文件写入错误,请重试!"<<endl; else{ for(int i=0;i<total;i++){outfile.write((char*)&member[i],sizeof(member[i]));outfile.write((char*)&bonus[i],sizeof(bonus[i]));} outfile.close();cout<<"文件写入成功!"<<endl<<endl; }
}void Department1::Infile_Department()
{int i=0;ifstream infile("information_department.dat",ios::binary);if(!infile) cerr<<"文件读取错误,请重试!"<<endl; else{while(infile.peek()!=EOF){ad((char*)&member[i],sizeof(member[i]));ad((char*)&bonus[i],sizeof(bonus[i]));i++;total++;}infile.close(); cout<<"销售部有"<<total<<"个员工的数据。"<<endl<<endl; }
}void main1(Base &bas,Department1 &dep1)//添加员工
{int choose1;Base *pt=&bas;cout<<"请选择即将添加员工的所在部门序号(1.人事部 2.销售部):";leap1:cin>>choose1;if(choose1<1||choose1>2){cout<<"请输入1或2:";goto leap1;}elseswitch(choose1){case 1:pt->Add_member();break;case 2:pt=&dep1;pt->Add_member();break; default:cout<<"输入有误,请重新输入:"<<endl;goto leap1;}
} void main2(Base &bas,Department1 &dep1)//删除员工
{int choose2;Base *pt=&bas;cout<<"请选择即将删除员工的所在部门序号(1.人事部 2.销售部):";leap2:cin>>choose2;if(choose2<1||choose2>2){cout<<"请输入1或2:";goto leap2;}elseswitch(choose2){case 1:pt->Delete_member();break; case 2:pt=&dep1;pt->Delete_member();break; default:cout<<"输入有误,请重新输入:"<<endl;goto leap2;}
} void main3(Base &bas,Department1 &dep1)//修改员工信息
{int choose3;Base *pt=&bas;cout<<"请选择即将修改员工的所在部门序号(1.人事部 2.销售部):";leap3:cin>>choose3;if(choose3<1||choose3>2){cout<<"请输入1或2:";goto leap3;}elseswitch(choose3){case 1:pt->Change_member();break; case 2:pt=&dep1;pt->Change_member();break; default:cout<<"输入有误,请重新输入:"<<endl;goto leap3;}
} void main4(Base &bas,Department1 &dep1)//按工资排序输出
{int choose4;Base *pt=&bas;cout<<"请选择即将输出的所在部门序号(1.人事部 2.销售部):";leap4:cin>>choose4;if(choose4<1||choose4>2){cout<<"请输入1或2:";goto leap4;}elseswitch(choose4){case 1:pt->Sort_by_wage();break; case 2:pt=&dep1;pt->Sort_by_wage();break; default:cout<<"输入有误,请重新输入:"<<endl;goto leap4;}
}void main5(Base &bas,Department1 &dep1)//按工资筛选员工
{int choose5;Base *pt=&bas;cout<<"请选择即将筛选的所在部门序号(1.人事部 2.销售部):";leap5:cin>>choose5;if(choose5<1||choose5>2){cout<<"请输入1或2:";goto leap5;}elseswitch(choose5){case 1:pt->Screen_by_wage();break; case 2:pt=&dep1;pt->Screen_by_wage();break; default:cout<<"输入有误,请重新输入:"<<endl;goto leap5;}
}void main6(Base &bas,Department1 &dep1)//按编号查找员工
{int choose6;Base *pt=&bas;cout<<"请选择即将查找的员工所在部门序号(1.人事部 2.销售部):";leap6:cin>>choose6;if(choose6<1||choose6>2){cout<<"请输入1或2:";goto leap6;}elseswitch(choose6){case 1:pt->LookUp_by_number();break; case 2:pt=&dep1;pt->LookUp_by_number();break; default:cout<<"输入有误,请重新输入:"<<endl;goto leap6;}
}int main()
{int choose; Base bas;Department1 dep1;bas.Infile_Base(); dep1.Infile_Department();while(1){ cout<<" "<<endl;cout<<" 人事管理系统 "<<endl; cout<<"***************************************************************"<<endl;cout<<"* *"<<endl;cout<<"* 1.添加员工 2.删除员工 *"<<endl;cout<<"* *"<<endl;cout<<"* 3.修改员工信息 4.按工资排序输出 *"<<endl;cout<<"* *"<<endl;cout<<"* 5.按工资筛选员工 6.按编号查找员工 *"<<endl;cout<<"* *"<<endl;cout<<"* 7.写入文件 0.退出程序 *"<<endl; cout<<"* *"<<endl; cout<<"***************************************************************"<<endl;cout<<" 请选择:";leap0:cin>>choose;if(choose<0||choose>7){cout<<"请输入0-7的数字:";goto leap0;}elseswitch(choose){case 1:main1(bas,dep1);break; case 2:main2(bas,dep1);break; case 3:main3(bas,dep1);break;case 4:main4(bas,dep1);break;case 5:main5(bas,dep1);break;case 6:main6(bas,dep1);break;case 7:bas.Outfile_Base();dep1.Outfile_Department();break;case 0:exit(0); default:cout<<"输入有误,请重新输入:"<<endl;goto leap0;}}return 0;
}
遗留及待优化问题
1.结构体Member(员工信息)中数据项仅有编号、姓名、工资3种。
2.派生类只有一个,可录入信息的部门只有两个,无法更好地体现出多态性。
3.增加的员工录入文件时,文件指针直接指向文件尾会更高效。
4.无法将基类和派生类(两个部门所有员工)的信息进行比较,共同排序,只能单独对每个部门进行比较和排序。
仅作留档。
本文发布于:2024-01-29 04:06:29,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170647239212571.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |