1、问题描述:
设计一个学校职工管理系统,要求实现如下功能:建立职工信息数据,
包括职工编号、姓名、 性别、工资、出生时间、岗位、参加工作时间和年
龄(必须计算得到),初始模拟数据通过文本文件创建(记录不少于 20 个),
通过程序载入。求职工(工人和教师分开)的平均年龄;查找、添加或删
除一个雇员;浏览全部信息等。
2、设计要求:
(1)使用继承的方法构造 3 个类,(即雇员类——虚基类,教师类(有
职称和所在系,按职称工资发工资)和工人类(有技术级和部门,按技术
级发工资) ——派生类),另外再设计一个管理类,实现对职工的管理;
(2)用文本编辑器编辑一个文本文件(总数 20 人以上)包含各类人
员的信息,程序运行时进行初始化数据, 使用 vector 数组存放对象指针。
并能保存数据为磁盘文件。
(3)编写同名 display()成员函数既虚函数,用来输出所有雇员的信
息。要求对“<<” 和“>>” 运算符进行重载,实现信息的输入,输
出。
(4)菜单功能: 添加人员,修改人员信息,浏览人员信息,按姓名
查找,平均年龄,删除人员。
3、问题的解决方案:
根据系统功能要求,可以将问题解决分为以下步骤:
(1)应用系统分析,建立该系统的功能模块框图以及界面的组织和设
计;
(2)分析系统中的各个实体及它们之间的关系;
(3)根据问题描述,设计系统的类层次;
(4)完成类层次中各个类的描述;
(5)完成类中各个成员函数的定义;
(6)完成系统的应用模块;
(7)功能调试;
(8)完成系统总结报告。
代码如下,仅供参考:
头文件 HEAD,h
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define SIZE 5
/*-------------------------------------全局变量-------------------------------------*/
/*定义在头文件中的全局变量,每被#include一次,就会被声明定义一次,申请一块新内存*/
static int g_num_t; //教师总人数
static int g_num_w; //职工总人数
static int g_age_t = 0; //教师总年龄
static int g_age_w = 0; //职工总年龄
/*-------------------------------------日 期 类-------------------------------------*/
class Date
{
private:
int year;
int month;
int day;
public:
Date(int y = 1919,int m = 1, int d = 1):year(y),month(m),day(d) {}
~Date() {}
istream & operator>>(istream &in);
ostream & operator<<(ostream &out) const;
int GetAge() const; //返回至今过了多少年,用于求年龄
bool Chack(); //检查输入日期是否合法
};
/*避免用友元的方式实现运算符的输出方式*/
istream & operator>>(istream &in,Date &date);
ostream & operator<<(ostream &out,const Date &date);
/*-------------------------------------共 有 类-------------------------------------*/
class Person//公有类
{
protected:
int number; //编号
int salary; //工资
int age; //年龄
string name; //姓名
string sex; //性别
string post; //岗位
Date birthtime; //出生时间
Date worktime; //参加工作
public:
//virtual bool display(); //输出成员信息
};
/*------------------------教 师 类--------------------------------------*/
class Teacher: public Person //教师类
{
protected:
string position; //职称
string department; //所在系
public:
Teacher(){}
~Teacher() {}
string Name() const; //获取姓名 用于按姓名查找
int Number() const; //获取编号 用于按编号查找 检查编号是否输入正确
void display()const; //显示个人信息
int Getage() const; //获得年龄 用于求平均年龄
int Getnum() const; //获得编号 检查编号是否输入正确
bool CheckBirthData(); //检查输入的出生日期是否合法
bool CheckWorkData (); //检查输入的参加工作日期是否合法
istream & operator>>(istream &in);
ostream & operator<<(ostream &out) const;
};
istream & operator>>(istream &in,Teacher &teacher);
ostream & operator<<(ostream &out,const Teacher &teacher);
/*------------------------职 工 类--------------------------------------*/
class Worker: public Person //职工类
{
protected:
string Technical; //技术级
string department; //部门
public:
Worker() {}
~Worker() {}
string Name() const; //获取姓名 用于按姓名查找
int Number() const; //获取编号 用于按编号查找
void display()const; //显示个人信息
int Getage() const; //获得年龄 用于求平均年龄
bool CheckBirthData(); //检查输入的出生日期是否合法
bool CheckWorkData (); //检查输入的参加工作日期是否合法
istream & operator>>(istream &in);
ostream & operator<<(ostream &out) const;
};
istream & operator>>(istream &in,Worker &worker);
ostream & operator<<(ostream &out,const Worker &worker);
/*------------------------管 理 类--------------------------------------*/
class Manage
{
private:
vector Teachdata;
vector Workdata;
public:
Manage() {LoadData();}
~Manage()
{
SaveData(); //保存数据 程序正常退出才会保存数据
FreeTeacher(); //释放new出的堆空间
FreeWorker();
}
void SaveData() const; //保存数据
void LoadData(); //加载数据
void MainMenu(); //主菜单
bool AddTeacher(); //增加教师
bool AddWorker(); //增加职工
void DelItemTeacher(); //删除教师
void DelItemWorker(); //删除职工
bool FindTeacher_name(string _name); //查找教师-按姓名
bool FindWorker_name(string _name); //查找职工-按姓名
bool FindTeacher_num(int _num); //查找教师-按编号
bool FindWorker_num(int _num); //查找职工-按编号
void UpdateTeacher(); //修改教师
void UpdateWorker(); //修改职工
void ShowDataTeacher()const; //输出教师
void ShowDataWorker()const; //输出职工
void Aver_ageTeacher(); //输出教师平均年龄
void Aver_ageWorker(); //输出职工平均年龄
void MangeTeacher(); //二级菜单——管理教师 实现对教师的增删查改功能
void MangeWorker(); //二级菜单——管理职工 实现对职工的增删查改功能
void FreeTeacher(); //释放new出的空间
void FreeWorker(); //释放new出的空间
/* 说明:vector存储的对象指针,在增加对象时用到new构建对象,析构时需要手动释放new出的空间 */
};
/* 输入框提示 便于调整表格以适应数据输出 可并入各输出函数中 */
void Format_t();
void Format_w();
/* 可并入MangeTeacher()和MangeWorker()中 */
void TeacherMenu(); //教师菜单
void WorkerMenu(); //职工菜单
头文件的实现 HEAD.cpp
#include"HEAD.h"
/*-------------------------------------日 期 类-------------------------------------*/
istream & Date::operator>>(istream &in)
{
//char ch;
//in>>year>>ch>>month>>ch>>day; /*输入格式:'/'分隔*/
in>>year>>month>>day; /*输入格式:空格分隔*/
return in;
}
ostream & Date::operator<<(ostream &out) const
{
//out<tm_year + 1900 - year;
}
bool Date::Chack()
{
time_t te = time(NULL); /*这句返回的只是一个时间戳*/
tm* t= localtime(&te);
int year = t->tm_year + 1900; /*最小年龄,当年出生,0岁*/
if(this->GetAge() < 0) return false; /* 未出生 */
if(this->year < (year-100) || this->year > year) return false;/*未出生或是已经出生但大于等于100岁(退休)*/
switch(month)
{
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
if(day<1 || day>31)
{
return false;
}
break;
case 4: case 6: case 9:case 11:
if(day<1 || day>30)
{
return false;
}
break;
case 2:
if(year % 4 ==0 && year % 100 !=0 || year % 400 ==0) /*是闰年*/
{
if(day<1 || day>29)
{
return false; /*闰年二月最多29天*/
}
else if(day<1 || day>28)
{
return false; /*平年二月最多28天*/
}
}
break;
default:
return false;
break;
}
return true;
}
istream & operator>>(istream &in,Date &date)
{
date>>in;
return in;
}
ostream & operator<<(ostream &out,const Date &date)
{
date<name;
}
int Teacher::Number()const
{
return this->number;
}
void Teacher::display()const
{
cout << *this << this->birthtime.GetAge() << endl;
}
bool Teacher::CheckBirthData()
{
return (this->birthtime).Chack();
}
bool Teacher::CheckWorkData()
{
return (this->worktime).Chack();
}
int Teacher::Getage()const
{
return this->birthtime.GetAge();
}
istream & Teacher::operator>>(istream &in)
{
in>>number>>name>>sex>>salary>>birthtime>>post>>worktime>>position>>department;
return in;
}
ostream & Teacher::operator<<(ostream &out) const
{
cout.width(5);
cout.fill(0);
out<>(istream &in,Teacher &teacher)
{
teacher>>in;
return in;
}
ostream & operator<<(ostream &out,const Teacher &teacher)
{
teacher<name;
}
int Worker::Number()const
{
return this->number;
}
void Worker::display()const
{
cout << *this << birthtime.GetAge() << endl;
}
int Worker::Getage()const
{
return this->birthtime.GetAge();
}
bool Worker::CheckBirthData()
{
return (this->birthtime).Chack();
}
bool Worker::CheckWorkData()
{
return (this->worktime).Chack();
}
istream & Worker::operator>>(istream &in)
{
in>>number>>name>>sex>>salary>>birthtime>>post>>worktime>>Technical>>department;
return in;
}
ostream & Worker::operator<<(ostream &out) const
{
cout.width(5);
cout.fill(0);
out<>(istream &in,Worker &worker)
{
worker>>in;
return in;
}
ostream & operator<<(ostream &out,const Worker &worker)
{
worker<::const_iterator it_w = Workdata.begin();
for(; it_w != Workdata.end(); ++it_w)
{
wout<< *(*it_w) <::const_iterator it_t = Teachdata.begin();
for(; it_t != Teachdata.end(); ++it_t)
{
tout<< *(*it_t) <>g_num_w;
for(int i = 0;i> *worker;
Workdata.push_back(worker);
g_age_w += worker->Getage();
}
win.close();
ifstream tin("Teacher.dat",ios::in);
if(!tin)
{
cout<<"打开失败,没有找到Teacher文件"<>g_num_t;
for(int i = 0;i> *teacher;
Teachdata.push_back(teacher);
g_age_t += teacher->Getage();
}
tin.close();
}
bool Manage::AddTeacher()
{
cout << "请依次输入:\t\t\t\t\t\t\"按Q/q取消\"" << endl;
Format_t();
cout << endl;
Teacher *te = new Teacher;
cin >> *te; //bug尚无法判断输入是否完整
cout << endl;
//清空缓冲区 防止输入错误进入死循环
cin.clear();
cin.sync();
/* 检验输入信息是否合法,不合法添加失败 */
if((te->Number()) >= pow(10.0,SIZE) || (te->Number()) <= 0)
{ /* 大于编号上限 或 编号输入错误,呈现负数 */
cout << "\t取消输入或编号输入错误,\n\t\t退出添加..." << endl;
return false;
}
if(FindTeacher_num(te->Number()))
{
cout << "\n警告:输入编号与已有人员重复,添加失败!!!\n";
return false;
}
if(!(te->CheckBirthData()))
{
cout << "\n警告:输入出生日期有误,添加失败\n";
return false;
}
if(!(te->CheckWorkData()))
{
cout << "\n警告:输入工作日期有误,添加失败\n";
return false;
}
if(FindTeacher_name(te->Name()))
{
cout << "\n提醒:输入姓名与已有人员重复\n";
}
Teachdata.push_back(te);
cout << "\t☆添加成功!!!☆" <> *tw; //bug尚无法判断输入是否完整
cout << endl;
//清空缓冲区 防止输入错误进入死循环
cin.clear();
cin.sync();
/* 检验输入信息是否合法,不合法添加失败 */
if((tw->Number()) >= pow(10.0,SIZE) || (tw->Number()) <= 0)
{ /* 大于编号上限 或 编号输入错误,呈现负数 */
cout << "\t取消输入或编号输入错误,\n\t\t退出添加..." << endl;
return false;
}
if(FindWorker_num(tw->Number()))
{
cout << "\n警告:输入编号与已有人员重复,添加失败!!!\n";
return false;
}
if(!(tw->CheckBirthData()))
{
cout << "\n警告:输入出生日期有误,添加失败\n";
return false;
}
if(!(tw->CheckWorkData()))
{
cout << "\n警告:输入工作日期有误,添加失败\n";
return false;
}
if(FindWorker_name(tw->Name())) /* 提醒重名,添加成功 */
{
cout << "\n提醒:输入姓名与已有人员重复\n";
}
Workdata.push_back(tw);
cout << "\t☆添加成功!!!☆" <>";
string _name;
cin >> _name;
vector::const_iterator it_t = Teachdata.begin();
while((*it_t)->Name() != _name)
{
++it_t;
if(it_t == Teachdata.end())
{
cout << "姓名输入错误,查无此人" <>";
string _name;
cin >> _name;
vector::const_iterator it_w = Workdata.begin();
while((*it_w)->Name() != _name)
{
++it_w;
if(it_w == Workdata.end())
{
cout << "姓名输入错误,查无此人" <>";
cin >> _name;
flg = true; //只查找
}
vector::const_iterator it_t = Teachdata.begin();
while((*it_t)->Name() != _name)
{
++it_t;
if(it_t == Teachdata.end())
{
cout << (flg == true ? "姓名输入错误,查无此人\n" : "" );
return false;
}
}
Format_t();
cout << "年龄" <display();
return true;
}
bool Manage::FindWorker_name(string _name = "") //查找职工
{
bool flg = false; //标记是只查找,还是被其他函数调用
if(_name == "")
{
cout << "请输入想要查询的姓名\n\t—>>" ;
cin >> _name;
flg = true; //只查找
}
vector::const_iterator it_w = Workdata.begin();
while((*it_w)->Name() != _name)
{
++it_w;
if(it_w == Workdata.end())
{
cout << (flg == true ? "姓名输入错误,查无此人\n" : "" );
return false;
}
}
Format_w();
cout << "年龄" <display();
return true;
}
bool Manage::FindTeacher_num(int _num = 0)
{
bool flg = false; //标记调用函数时,调用的查找功能还是利用该函数判断数据
if(_num == 0) /*flg=true调用查找功能,需要输出查找结果*/
{ /*flg=false 中判断真假,无需输出查找结果*/
cout << "请输入想要查询的编号\n\t>>";
cin >> _num;
flg = true;
}
//清空缓冲区 防止输入错误进入死循环
cin.clear();
cin.sync();
vector::const_iterator it_t = Teachdata.begin();
while((*it_t)->Number() != _num)
{
++it_t;
if(it_t == Teachdata.end())
{
cout << (flg == true ? "姓名输入错误,查无此人\n" : "" );
return false;
}
}
if(flg) //只查找
{
Format_t();
cout << "年龄" <display();
}
return true;
}
bool Manage::FindWorker_num(int _num = 0)
{
bool flg = false; //标记调用函数时,调用的查找功能还是利用该函数判断数据
if(_num == 0) /*flg=true调用查找功能,需要输出查找结果*/
{ /*flg=false 中判断真假,无需输出查找结果*/
cout << "请输入想要查询的编号\n\t>>";
cin >> _num;
flg = true;
}
//清空缓冲区 防止输入错误进入死循环
cin.clear();
cin.sync();
vector::const_iterator it_w = Workdata.begin();
while((*it_w)->Number() != _num)
{
++it_w;
if(it_w == Workdata.end())
{
cout << (flg == true ? "姓名输入错误,查无此人\n" : "" );
return false;
}
}
if(flg) //只查找
{
Format_w();
cout << "年龄" <display();
}
return true;
}
void Manage::UpdateTeacher() //修改教师-按编号
{
cout << "\t\t\t\t\t\t\"按'0'取消\"\n请输入想要修改的编号:\n\t—>>";
char _number;
cin >> _number;
//清空缓冲区 防止输入错误(非数字)进入死循环
cin.clear();
cin.sync();
/* 注:若输入了英文字符,会把该字符的ascall码写进_number中 */
vector::const_iterator it_t = Teachdata.begin();
while((*it_t)->Number() != _number)
{
++it_t;
if(it_t == Teachdata.end())
{
cout << "编号输入错误,查无此人" <>\n"<< *(*it_t) <<"\n(修改)请输入——>"<> *(*it_t);
cout << "修改成功" <>";
int _number = 0;
cin >> _number;
//清空缓冲区 防止输入错误(非数字)进入死循环
cin.clear();
cin.sync();
/* 注:若输入了英文字符,会把该字符的ascall码写进_number中 */
vector::const_iterator it_w = Workdata.begin();
while((*it_w)->Number() != _number)
{
++it_w;
if(it_w == Workdata.end())
{
cout << "编号输入错误,查无此人" <>\n"<< *(*it_w) <<"\n(修改)请输入——>"<> *(*it_w);
cout << "修改成功" <>>\t\t\t\t\t\t\t\t [按创建时间排序]" << endl;
Format_t();
cout << "年龄" <::const_iterator it_t = Teachdata.begin();
while(it_t != Teachdata.end())
{
(*it_t)->display();
++it_t;
}
}
void Manage::ShowDataWorker()const //输出数据
{
cout << "\n职工>>>\t\t\t\t\t\t\t\t [按创建时间排序]" << endl;
Format_w();
cout << "年龄" <::const_iterator it_w = Workdata.begin();
while(it_w != Workdata.end())
{
(*it_w)->display();
++it_w;
}
}
void Manage::Aver_ageTeacher()
{
cout << "\n教师>>>" << endl;
cout << "\n教师平均年龄:" << g_age_t/g_num_t << endl;
/* 增加功能:
通过循环遍历或者定义全局变量的方式,可以实现对不同
性别,不同职位的教师求平均年龄 */
}
void Manage::Aver_ageWorker()
{
cout << "\n职工>>>" << endl;
cout << "\n职工平均年龄:" << g_age_w/g_num_w << endl;
/* 增加功能:
通过循环遍历或者定义全局变量的方式,可以实现对不同
性别,不同职位的教师求平均年龄 */
}
void Manage::FreeTeacher()
{
vector::const_iterator it_w = Teachdata.begin();
while(it_w != Teachdata.end())
{
delete *it_w;
++it_w;
}
Teachdata.clear();
}
void Manage::FreeWorker()
{
vector::const_iterator it_w = Workdata.begin();
while(it_w != Workdata.end())
{
delete *it_w;
++it_w;
}
Workdata.clear();
}
void Manage::MainMenu()
{
int tag = 0;
do
{
cout<<"----------欢迎进入教职工信息管理系统--------------------"<";
cin>>tag;
//清空缓冲区 防止输入错误进入死循环
cin.clear();
cin.sync();
system("cls");
switch(tag)
{
case 0:
cout<<"\t\t感谢您的使用(^0^)\n\t\t退出系统中... 数据保存中......\n"<>\n\t>>>";
string _name;
cin >> _name;
if(!FindTeacher_name(_name))
{
if(!FindWorker_name(_name))
{
cout << "查无此人,查找失败" << endl;
}
}
cout << endl;
}
break;
case 5:
Aver_ageTeacher();
Aver_ageWorker();
cout << endl;
break;
case 6:
cout << "\n现任教师有>>" << g_num_t << "人\n"
<<"\n现任职工有>>" << g_num_w << "人\n" <> chose;
//清空缓冲区 防止输入错误进入死循环
cin.clear();
cin.sync();
system("cls");
switch (chose)
{
case 1: AddTeacher(); break; //添加功能
case 2: UpdateTeacher(); break; //修改功能
case 3: ShowDataTeacher(); break; //显示功能
case 4: FindTeacher_name(); break; //姓名查找功能
case 5: FindTeacher_num(); break; //编号查找功能
case 6: Aver_ageTeacher(); break; //平均年龄
case 7: DelItemTeacher(); break; //删除功能
default : //退出功能
system("cls");
return;
break;
}
}
cout <<"---------------------------------------------------------"<> chose;
//清空缓冲区 防止输入错误进入死循环
cin.clear();
cin.sync();
system("cls");
switch (chose)
{
case 1: AddWorker(); break; //添加功能
case 2: UpdateWorker(); break; //修改功能
case 3: ShowDataWorker(); break; //显示功能
case 4: FindWorker_name(); break; //姓名查找功能
case 5: FindWorker_num(); break; //编号查找功能
case 6: Aver_ageWorker(); break; //平均年龄
case 7: DelItemWorker(); break; //删除功能
default : //退出功能
system("cls");
return;
break;
}
}
cout <<"---------------------------------------------------------"<:";
}
void WorkerMenu() //职工菜单
{
cout<<"\n已进入:职工管理系统"<:";
}
void Format_t()
{
cout.width(6);;
cout << "教师编号 姓名 性别 工资 出生日期 岗位 参加工作时间 职称 所在系 \t";
}
void Format_w()
{
cout.width(6);;
cout << "职工编号 姓名 性别 工资 出生日期 岗位 参加工作时间 技术级 部门 \t";
}
主函数 main.cpp
#include "HEAD.h"
int main()
{
system("title 教职工管理系统");
Manage man;
man.MainMenu();
return 0;
}
数据文件保存在Teacher.dat和Worker.dat中
我看到评论和私信给我,确实我的程序存在一些问题,相关解决方案已发布至新的博文中连接如下: https://blog.csdn.net/weixin_43919932/article/details/106663320