写一个简单的职工信息管理系统

目前为止,C++的三大特性封装、继承、多态基本上都学习完了,现在用一个职工管理系统来结束和总结这一阶段的学习

项目

项目名称:职工信息管理系统

项目需求:
  1. 添加职工信息,并且支持批量添加,能保存添加进来职工信息
  2. 显示职工信息
  3. 删除职工信息
  4. 修改职工信息
  5. 查找职工信息,可以选择是根据名字查找还是根据编号查找,如果是根据名字查找则必须查找出所有名字符合的人的信息
  6. 给存贮的信息排序,可以是升序或者降序
  7. 清空所有信息
  8. 退出系统
项目思路:
  1. 职工的有很多职位,有普通员工,经理,老板等等,所以应该创建一个职工的抽象类,用多态来满足不同职位的信息显示和存储
  2. 对于职工信息的存贮可以创建一个专门用来存储信息的 data.txt 文件,用C++对文件进行读写和排序
  3. 整个系统由switch语句识别用户输入的指令并进行相应的操作

Code

依照惯例,先搭建出整个系统的大致框架

首先是将整个管理系统封装成一个类:labourManager ,有两个属性,一个是人员个数计数器(empNumber),一个是用于存贮人员信息数组的指针(empArry,是二阶指针) ,用于实现整个系统的功能(在main中实例化一个管理系统类即可);

其次是一个职工抽象类:worker , 三个属性:职工编号(id),职工姓名(name),职业编号(deptid);

最后是主函数,实例化系统类,switch控制系统功能选择与执行

下图是整个项目的结构
项目目录.png

worker.h

是职工的抽象类声明

#pragma once
#include<iostream>
#include<string>

using namespace std;


//职工抽象类
class worker
{
public:
	//职工编号
	int id;
	//职工姓名
	string name;
	//部门编号
	int deptId;

	//构造函数
	worker(int i, string n, int d) :id(i), name(n), deptId(d) {};

	//显示个人信息
	virtual void showInfo() = 0;

	//获取岗位名称
	virtual string getDeptName() = 0;
};



尽管抽象类不能实例化,但是不妨碍有构造函数

employee.h

这是普通职工类

#pragma once
#include<iostream>
#include"worker.h"
#include<string>

using namespace std;
class employee : public worker
{
public:

	//构造函数
	employee(int i,string n,int d):worker(i,n,d){};
	
	//重写worker抽象类的纯虚函数
	void showInfo();

	string getDeptName();

};


employee.cpp
#include "employee.h"

//纯虚函数的实现

void employee::showInfo() {
	cout << "\tlabour's id:" << this->id;
	cout << "\tlabour;s name:" << this->name;
	cout << "\tlabour;s depatment:" << this->getDeptName();
	cout << "\tlabour's task" << endl; //这表示职工的工作任务,统一简写了
 }


string employee::getDeptName() {
	return "employee";
}

经理类和老板类依葫芦画瓢实现即可,这里不再过多赘述

功能实现

所需的类创建好之后就要考虑系统功能的实现,由于对读写文件功能的设计,我们还需要在 labourManager 里面加入几个方便我们实现这一功能和系统初始化的函数和属性

首先需要一个简单的功能菜单界面

功能菜单
void labourManager:: showMeun() {
	cout << "=======================================================" << endl;
	cout << "			LabourManager			" << endl;
	cout << "=======================================================" << endl;
	cout << "		1-add labour information	" << endl;
	cout << "		2-show labour information	" << endl;
	cout << "		3-delete labour information	" << endl;
	cout << "		4-change labour information	" << endl;
	cout << "		5-find labour information	" << endl;
	cout << "		6-sort labour information	" << endl;
	cout << "		7-clear all information		" << endl;
	cout << "		0-exit system				" << endl;
	cout << "=======================================================" << endl;
	cout << endl;
}

接着在写labourManager的构造函数时,我们要考虑到,在构造函数要应对几种情况

  1. 第一次初始化系统,则职工数据文件都不存在
  2. 文件存在但是是空文件
  3. 文件已经存在了,里面存有数据

因此,我们给系统类 labourManager 增加一个用于表示文件是否为空的属性:bool fileIsEmpty;若数据文件不存在或者是空文件则返回true,否则返回false;又因为在第三种情况下要将存贮在数据文件中的数据写到系统类中,所以又增加了一个初始化系统类数组的函数 void initEmp()以及专门用来获取文件中人数的函数int get_fileEmpNunmber();

void initEmp()

具体内容如下

//初始化数组
void labourManager::initEmp() {

	//先把文件中的数据读出来
	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	
	int id;
	string name;
	int deptId;

	int index = 0;

	//把读出来的数据放入数组中
	while (ifs >> id && ifs >> name&& ifs >> deptId)
	{
		worker* worker = NULL;

		switch (deptId) {
		case 1:
			//读出来是普通员工
			worker = new employee(id, name, deptId);
			break;
		case 2:
			//读出来是经理
			worker = new manager(id, name, deptId);
			break;
		case 3:
			//读出来是老板
			worker = new boss(id, name, deptId);
			break;
		}

		this->empArray[index] = worker;
		index++;
	}

	ifs.close();

}


注:在labourManager头文件中声明了了#define FILENAME “labourdata.txt”

int get_fileEmpNunmber()
int labourManager::get_fileEmpNunmber() {

	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	int id;
	string name;
	int deptId;

	int count = 0; //人数计数器

	while (ifs >> id&&ifs >> name&&ifs>>deptId) //读一行就自增一次,一直读完,就能计算出有多少行
	{
		count++;
	}

	ifs.close();

	return count;
}


然后应对三种不同的情况使系统类初始化

labourManager::labourManager()
{
	//对于构造函数,要分三种情况来进行构造
	//1-第一次初始化系统,则职工数据文件都不存在
	//先打开文件
	ifstream ifs;
	ifs.open(FILENAME, ios::in);

	if (!ifs.is_open()) {	//判断是否打开成功,若否,则没有数据文件,是第一次初始化系统
		cout << "file isn't exist!" << endl;
		//初始化属性
		this->empArray = NULL;
		this->empNumber = 0;
		//标明数据文件不存在
		this->fileIsEmpty = true;
		//关闭文件
		ifs.close();
		return;
	}

	//2-若文件存在但是是空文件
	char index;
	ifs >> index; // 读一个字符s


	if (ifs.eof()) {   //	eof()函数判断读到的字符是否是EOF,若是,则是空文件
		cout << "the data is empty!" << endl;
		//初始化属性
		this->empArray = NULL;
		this->empNumber = 0;
		//标明数据文件不存在
		this->fileIsEmpty = true;
		//关闭文件
		ifs.close();
		return;
	}


	//3-文件已经存在了,则读出里面的人数
	this->empNumber = get_fileEmpNunmber();
	cout << "the file is exist,the quantity in file is: " << this->empNumber << endl;
	//读入数据
	this->empArray = new worker * [this->empNumber];
	initEmp();


}

labourManager::~labourManager()
{
	if (empArray != NULL)
	{
		delete empArray;
		empArray = NULL;
	}
}

除此之外,还需要一个每次改变都能如实将影响传输到数据文件中的函数save()

save()
//存储数据的函数
void labourManager::save() {
	ofstream ofs;
	ofs.open(FILENAME, ios::out); //用输出方式打开文件
	for (int i = 0; i < this->empNumber; i++) { //录入数据
		ofs << this->empArray[i]->id << " "
			<< this->empArray[i]->name << " "
			<< this->empArray[i]->deptId << endl;
	}

	ofs.close(); //关闭文件
}

然后开始写添加职工信息的功能

添加职工信息
void labourManager::addLabourInfo() {

	int addNumber = 0;
	cout << "the quantity you want to add:" << endl;	//输入要添加的数目

	cin >> addNumber;

	if (addNumber > 0) {
		//计算要新开辟的空间大小
		int newSize = this->empNumber + addNumber;

		//开辟新的空间
		worker** newspace = new worker*[newSize];

		//将原空间下的内容放到现有的新空间下
		if (this->empArray != NULL) {
			for (int i = 0; i < this->empNumber; i++) {
				newspace[i] = this->empArray[i];
			}
		}

		//往后添加新的数据
		for (int i = 0; i < addNumber;i++) {
			int id = 0;
			string name;
			int deptId = 0;
			cout << "please enter NO." << i + 1 << "labour's id:" << endl;
			cin >> id;

			cout << "please enter NO." << i + 1 << "labour's name:" << endl;
			cin >> name;

			cout << "please enter NO." << i + 1 << "labour's department id:" << endl;
			cout << "1-emplpyee" << endl;
			cout << "2-manager" << endl;
			cout << "3-boss" << endl;
			cin >> deptId;

			//利用多态给基类赋值
			worker* worker = NULL;
			switch (deptId)
			{
			case 1:
				worker = new employee(id,name,1);
				break;
			case 2:
				worker = new manager(id, name, 2);
				break;
			case 3:
				worker = new boss(id, name, 3);
				break;
			default:
				break;
			}

			//将信息保存到数组中
			newspace[this->empNumber + i] = worker;
		}

		//释放原有空间
		delete[] this->empArray;

		//更改新空间的指向
		this->empArray = newspace;

		//更新新员工人数
		this->empNumber = newSize;

		//将文件为空的表示符置否
		this->fileIsEmpty = false;

		//输入完毕保存数据
		this->save();

		//提示操作成功
		cout << "add sucessful!" << endl;

	}
	else
	{
		//输入的无效数,报错
		cout << "number is wrong!" << endl;
	}
	system("pause");

}


在写显示信息之前,我们要想到,可能有数据文件里面不存在这个人的情况
所以需要判断一下数据里面是否存贮了这个人的信息的函数,而且后面的其他功能也会用到这个判断

判断函数 isExist()
//判断是否存在所选的职工信息,是则返回对应的位置,不是则返回-1
int labourManager::isExist(int id) {
	int index = -1; //默认不存在

	for (int i = 0; i < this->empNumber; i++) {
		if (this->empArray[i]->id == id) {
			index = i;
			break;
		}
			
		
	}

	return index;
}


显示职工信息
//职工信息显示函数
void labourManager::showLabourInfo() {

	//先判断文件是否存在或者是否为空
	if (fileIsEmpty)
		cout << "file dosen't exist or file is empty!" << endl;
	else
	{
		//若文件内容不为空,则显示数据
		for (int i = 0; i < this->empNumber; i++)
			this->empArray[i]->showInfo();
	}

	system("pause");
}


删除职工信息

//删除职工信息
void labourManager::deleteLabourInfo() {


	//先判断是否为空文件
	if (this->fileIsEmpty) {
		cout << "the file is empty!" << endl;
	}

	else
	{
		//接收想要删除的职工的编号
		int id = 0;
		cout << "the labour's id you want to delete" << endl;
		cin >> id;

		//  判断数据中是否存在这名员工
		int index = this->isExist(id);

		if (index == -1) {
			cout << "delete fail" << endl;
		}
		else
		{
			for (int i = index; i < this->empNumber - 1; i++) {

				this->empArray[i] = this->empArray[i + 1];

			}
			this->empNumber--; //更新数组
			this->save(); //保存数据
			cout << "delete sucessful!" << endl;

		}
	}
	system("pause");

}



修改职工信息
//修改职工信息
void labourManager::changeLabourInfo() {

	//先判断文件是否为空
	if(this->fileIsEmpty)
		cout << "file dosen't exist or file is empty!" << endl;
	else
	{	//不为空则查找想要修改的人的编号
		int id = 0;
		cout << "the labour's id you want to change: " << endl;
		cin >> id;


		int ret = this->isExist(id);
		
		if (ret == -1)
			//如果没找到,打出提示
			cout << "this one doesn't exist!" << endl;
		else
		{
			//找到了要修改的员工位置
			delete this->empArray[ret];	//先删除掉节点信息

			int newId = 0;
			string newName = "";
			int newDeptId = 0;

			//开始重新录入信息
			cout << "NO." << id << " labour's new id is: " << endl;
			cin >> newId;
			cout << "new name is: " << endl;
			cin >> newName;
			cout << "new department id is: " << endl;
			cout << "1-employee" << endl;
			cout << "2-manager" << endl;
			cout << "3-boss" << endl;
			cin >> newDeptId;

			worker* worker = NULL;

			switch (newDeptId)
			{

			case 1:
				worker = new employee(newId, newName, newDeptId);
				break;
			case 2:
				worker = new manager(newId, newName, newDeptId);
				break;
			case 3:
				worker = new boss(newId, newName, newDeptId);
				break;
			default:
				break;
			}

			//让原来的指针重新指向新的节点
			this->empArray[ret] = worker;

			//更新数据
			this->save();

			cout << "change sucessful!" << endl;


		}
		system("pause");
	}
}


查找职工信息
//查找职工信息
void labourManager::findLabourInfo() {

	//先判断文件是否存在
	if (this->fileIsEmpty) {
		cout << "file is empty!" << endl;
	}
	else
	{	
		//若存在,选择查找的方式 1-按id号  2-按名字
		int select = 0;
		cout << "the way you find:" << endl;
		cout << "1-by id" << endl;
		cout << "2-by name" << endl;
		cin >> select;

		if (select == 1) {	//如果按id查找
			int id;
			cout << "the labour;s id you want to find" << endl;
			cin >> id;		//输入目标职工id

			int ret = this->isExist(id);	//判断id在文件中是否存在

			if (ret == -1) {
				cout << "this one doesn't exist!" << endl;
			}
			else
			{
				// 找到存在则显示
				cout << "find sucessful!" << endl;
				this->empArray[ret]->showInfo();
			}
		}
		//按名字查找
		else if (select ==2) {
			string name = "";
			cout << "the labour's name you want to find" << endl;
			cin >> name;
			bool index = false;		//用于判断是否找到,默认是false
			for (int i = 0; i < this->empNumber; i++) {
				if (this->empArray[i]->name == name) {
					//cout << "find sucessful!" << endl;
					this->empArray[i]->showInfo();
					index = true;	//找到了则true
				}
			}

			if(index == false) //没找打则输出提示
				cout << "this one doesn't exist!" << endl;
		}
		else
		{
			//输入的不是有数字
			cout << "wrong number! pls try again" << endl;
		}

	}

	//暂停,查看信息
	system("pause");
}


给职工信息排序

//给文件中的内容排序
void labourManager::sortLabourInfo() {
	//先判断文件是否存在
	if (this->fileIsEmpty) {
		cout << "file is empty!" << endl;
	}
	else
	{
		//选择方式
		int select = 0;
		cout << "the way you sort:" << endl;
		cout << "1-ASC" << endl; //升序
		cout << "2-DESC" << endl;	//降序
		cin >> select;

		//利用选排给信息进行排序
		for (int i = 0; i < this->empNumber;i++) {
			int MIN = i;
			for (int j = i + 1; j < this->empNumber; j++) {
				if (select == 1) { //采取升序
					if (this->empArray[MIN]->id > this->empArray[j]->id)
						MIN = j;
				}
				else
				{
					//采取降序
					if (this->empArray[MIN]->id < this->empArray[j]->id)
						MIN = j;

				}
			}

			//实行交换,保证是最小/最大的
			if (MIN != i) {
				worker* temp = this->empArray[i];
				this->empArray[i] = this->empArray[MIN];
				this->empArray[MIN] = temp;
			}
		}

		cout << "sort sucessful!" << endl;
		this->save(); //保存数据
		this->showLabourInfo(); //显示数据
	}

	system("pause");
}


清空所有数据
void labourManager::clearAll() {

	int select = 0;
	cout << "Do you want to clear data?" << endl;
	cout << "1-Yes" << endl;
	cout << "2-No" << endl;
	cin >> select;

	if (select) {
		ofstream ofs;
		ofs.open(FILENAME, ios::trunc);
		ofs.close();

		if (this->empNumber != NULL) {
			for (int i = 0; i < this->empNumber;i++) {
				if (this->empArray[i] != NULL) {
					delete this->empArray[i];
				}
			}

			this->empNumber = 0;
			delete[] this->empArray;
			this->empArray = NULL;
			this->fileIsEmpty = true;
		}

		cout << "clear sucessful!" << endl;
	}

	system("pause");
}

这样,整个管理系统就完结了

最后附上完整项目的代码
labourManager.zip

总结

这次是职工管理系统,用到了封装、多态、继承以及文件的读写,算是大部分所学知识都用上去了;但是感觉还能优化,比如这样的管理系统和数据库就很搭,给数据排序,查找,删除等操作都要简化不少,下次就朝这个方向改造

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值