面向对象程序设计实训 人事管理系统

一、设计题目
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)
		{
			infile.read((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)
		{
			infile.read((char*)&member[i],sizeof(member[i]));
			infile.read((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;
    }
	else
    switch(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;
	}
	else
	    switch(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;
	}
	else
		switch(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;
	}
	else
		switch(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;
	}
	else
		switch(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;
	}
	else
		switch(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;
	    }
		else
		     switch(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.无法将基类和派生类(两个部门所有员工)的信息进行比较,共同排序,只能单独对每个部门进行比较和排序。

仅作留档。

发布了30 篇原创文章 · 获赞 12 · 访问量 883

猜你喜欢

转载自blog.csdn.net/weixin_43893854/article/details/104322040
今日推荐