提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
管理系统中需要实现的功能如下:
退出管理程序:退出当前管理系统
增加职工信息:实现批量添加职工功能,将信息录入到文件中,职工信息为:职工编号、姓名、部门编号
显示职工信息:显示公司内部所有职工的信息
删除离职职工:按照编号删除指定的职工
修改职工信息:按照编号修改职工个人信息
查找职工信息:按照职工的编号或者职工的姓名进行查找相关的人员信息
按照编号排序:按照职工编号,进行排序,排序规则由用户指定
清空所有文档:清空文件中记录的所有职工信息(清空前需要再次确认,防止误删)
#pragma once//防止头文件重复包含,与下面C语言的ifndef差不多
#ifndef WORKERMANGER__H
#define WORKERMANGER__H
#include <iostream>
using namespace std;
class WorkerManger {
public:
//构造函数
WorkerManger();
//析构函数
~WorkerManger();
};
#endif // !1
#include <iostream>
#include "workerManager.h"
WorkerManger::WorkerManger() {
}
WorkerManger::~WorkerManger() {
}
没啥好说的,直接写就完事了。
void WorkerManger::showMenu() {
cout << "****************************************" << endl;
cout << "按'0'——退出管理程序" << endl;
cout << "按'1'——增加职工信息" << endl;
cout << "按'2'——显示职工信息" << endl;
cout << "按'3'——删除离职职工" << endl;
cout << "按'4'——修改职工信息" << endl;
cout << "按'5'——查找职工信息" << endl;
cout << "按'6'——按照编号排序" << endl;
cout << "按'7'——清空所有文档" << endl;
cout << "****************************************" << endl;
}
代码如下:
void WorkerManger::exitSystem() {
cout << "欢迎再次使用" << endl;
system("pause");
exit(0);
}
这里要注意:纯虚函数根本不需要在.c文件去定义
#pragma once
#include <iostream>
#include <string>
using namespace std;
//一个抽象的worker类
class abstractWorker {
public:
//打印岗位信息描述的虚函数
virtual void showInfo() = 0;
//获取岗位名称的虚函数
virtual void getDeptname() = 0;
//职工编号
int worker_ID;
//职工姓名
string worker_name;
//等级
int Dept_ID;
};
employee.h
#pragma once
#include <iostream>
#include <string>
#include "worker.h"
using namespace std;
//一个表示员工的子类,继承自抽象的worker类
class employee:public abstractWorker {
public:
//初始化成员变量的构造函数
employee(int mID, string name, int dID);
//打印岗位信息描述的函数
void showInfo();
//获取岗位名称的函数
string getDeptname();
};
employee.c
#include <iostream>
#include "worker.h"
#include "employee.h"
//构造函数,初始化员工信息
employee::employee(int mID,string name,int dID) {
this->worker_ID = mID;
this->worker_name = name;
this->Dept_ID = dID;
}
//打印岗位信息描述的函数
void employee::showInfo() {
cout << "职工编号为:" << this->worker_ID<<"\t"
<< "职工姓名为:" << this->worker_name << "\t"
<< "职工岗位编号为:" << this->getDeptname() << "\t"
<<"岗位职责是完成经理交代的任务" << "\t"
<< endl;
}
//获取岗位名称的函数
string employee::getDeptname() {
return string("员工");
}
manner.h
#pragma once
#include <iostream>
#include <string>
#include "worker.h"
using namespace std;
//一个表示员工的子类,继承自抽象的worker类
class manner :public abstractWorker {
public:
//初始化成员变量的构造函数
manner(int mID, string name, int dID);
//打印岗位信息描述的函数
void showInfo();
//获取岗位名称的函数
string getDeptname();
};
manner.c
#include <iostream>
#include "worker.h"
#include "manner.h"
//构造函数,初始化员工信息
manner::manner(int mID, string name, int dID) {
this->worker_ID = mID;
this->worker_name = name;
this->Dept_ID = dID;
}
//打印岗位信息描述的函数
void manner::showInfo() {
cout << "职工编号为:" << this->worker_ID << "\t"
<< "职工姓名为:" << this->worker_name << "\t"
<< "职工岗位编号为:" << this->getDeptname() << "\t"
<< "岗位职责是完成老板交代的任务,并下发给员工" << "\t"
<< endl;
}
//获取岗位名称的函数
string manner::getDeptname() {
return string("经理");
}
boss.h
#pragma once
#include <iostream>
#include <string>
#include "worker.h"
using namespace std;
//一个表示老板的子类,继承自抽象的worker类
class boss :public abstractWorker {
public:
//初始化成员变量的构造函数
boss(int mID, string name, int dID);
//打印岗位信息描述的函数
void showInfo();
//获取岗位名称的函数
string getDeptname();
};
boss.c
#include <iostream>
#include "worker.h"
#include "boss.h"
//构造函数,初始化员工信息
boss::boss(int mID, string name, int dID) {
this->worker_ID = mID;
this->worker_name = name;
this->Dept_ID = dID;
}
//打印岗位信息描述的函数
void boss::showInfo() {
cout << "职工编号为:" << this->worker_ID << "\t"
<< "职工姓名为:" << this->worker_name << "\t"
<< "职工岗位编号为:" << this->getDeptname() << "\t"
<< "岗位职责是总管全局" << "\t"
<< endl;
}
//获取岗位名称的函数
string boss::getDeptname() {
return string("老板");
}
面临的问题是:不同的职工类创建出来的对象类型不同,比如创建了三个employee对象、两个manner对象和一个boss对象,他们很难统一的管理和操作,没办法有序的排布在表中。
employee e1(1, "小明", 2);
employee e2(2, "小花", 3);
manner m1(3, "李哥", 4);
boss b1(4, "王总", 5);
像这样单纯实例化对象,但是他们都是分散的,没有办法很好的有序的建立其联系来。
abstractWorker* worker[max_count];
//一个一个的增加职工信息的函数
void WorkerManger::addInformation(abstractWorker* worker[]) {
int mId;
string name;
string dept;
cout << "请输入职工的ID号:";
cin >> mId;
cout << "请输入职工的姓名:";
cin >> name;
cout << "请输入职工的职位:";
cin >> dept;
if (dept == "员工") {
worker[person_index] = new employee(mId, name, 1);
}
else if (dept == "经理") {
worker[person_index] = new manner(mId, name, 2);
}
else if (dept == "老板") {
worker[person_index] = new boss(mId, name, 3);
}
else {
cout << "无效的职位类型!" << endl;
return;
}
cout << "职工信息添加成功!" << endl;
person_index++;
}
代码很简单,也很清楚。这里最巧妙的就是用到了父类的指针数组来统一访问不同子类的属性,实现了多态。
但是问题又来了,一个公司一般有成百上千人,如果一个个添加,就非常浪费时间,那么能否优化代码,可以实现成批的大量的添加职员信息呢?
//一个可以批量添加员工信息的函数
void WorkerManger::manyaddinformation(abstractWorker* worker[], ofstream& ofs) {
// 检查文件是否为空
bool fileIsEmpty = ofs.tellp() == 0;
if (fileIsEmpty) {
ofs << "ID\t姓名\t等级\t岗位" << endl;
}
cout << "请输入添加职工数量:" << endl;
int addNum = 0;
cin >> addNum;
if (addNum > 0) {
for (int i = 0; i < addNum; i++) {
int type = 0;
cout << "请输入第 " << i + 1 << " 个职工类型:" << endl;
cout << "1、员工" << endl;
cout << "2、经理" << endl;
cout << "3、老板" << endl;
cin >> type;
string name;
cout << "请输入职工姓名:" << endl;
int id;
int dSelect;
cin >> name;
switch (type) {
case 1: // 普通职工
worker[person_index] = new employee(person_index + 1, name, 1);
break;
case 2: // 经理
worker[person_index] = new manner(person_index + 1, name, 2);
break;
case 3: // 老板
worker[person_index] = new boss(person_index + 1, name, 3);
break;
default:
break;
}
person_index++; // 每添加一个人员,人数增加1
ofs << worker[person_index - 1]->worker_ID << "\t"
<< worker[person_index - 1]->worker_name << "\t"
<< worker[person_index - 1]->level << "\t"
<< worker[person_index - 1]->getDeptname() << endl;
}
cout << "成功添加" << addNum << "名职工!" << endl;
}
else {
cout << "输入数据有误!" << endl;
}
system("pause");
system("cls");
}
我想让表头永远有一个说明,但是出了问题,就是每次重新添加职员信息时,都会重新添加一次 “ID\t姓名\t等级\t岗位” ,我很不理解,明明自己做了文件为空和不为空的判断,但是无论怎样都会重新打印。
首先,在 WorkerManger 类的头文件中声明文件流成员变量:
class WorkerManger {
private:
ofstream ofs; // 文件流对象
// 其他成员变量和函数声明
};
然后,在类的构造函数中打开文件流,并在析构函数中关闭文件流:
WorkerManger::WorkerManger() {
ofs.open("worker.txt", ios::app); // 打开文件流,以追加模式写入
}
WorkerManger::~WorkerManger() {
ofs.close(); // 关闭文件流
}
这样的话,调用manger.manyaddinformation(worker);就只用传一个参数了。
1.点h文件中引入文件头文件和宏定义
#include <fstream>
#define fliename "worker.txt"
2.代码实现
//保存职工信息到文件中
void WorkerManger::saveinfo(abstractWorker* worker[]) {
ofstream ofs;
ofs.open(filename, ios::out);
ofs << "ID\t姓名\t等级\t岗位" << endl;
for (int i = 0; i < person_index; i++) {
ofs << worker[i]->worker_ID << "\t"
<< worker[i]->worker_name << "\t"
<< worker[i]->level << "\t"
<< worker[i]->getDeptname() << endl;
}
}
string getPositionFromLine(const string& line) {
// 假设岗位信息在第4列,以制表符分隔
stringstream ss(line);
string token;
for (int i = 0; i < 3; i++) {
getline(ss, token, '\t');
}
getline(ss, token, '\t');
return token;
}
void WorkerManger::readflie() {
ifstream ifs(filename);
if (ifs.is_open()) {
string line;
int totalEmployees = 0;
int totalManagers = 0;
int totalBosses = 0;
while (getline(ifs, line)) {
// 处理每行内容
cout << line << endl;
// 每行内容的格式为:ID\t姓名\t等级\t岗位
// 假设岗位信息在第4列
string position = getPositionFromLine(line);
// 根据岗位信息进行计数
if (position == "员工") {
totalEmployees++;
}
else if (position == "经理") {
totalManagers++;
}
else if (position == "老板") {
totalBosses++;
}
}
ifs.close();
// 输出统计结果
cout << "员工人数:" << totalEmployees << endl;
cout << "经理人数:" << totalManagers << endl;
cout << "老板人数:" << totalBosses << endl;
cout << "总共人数:" << totalEmployees + totalManagers + totalBosses << endl;
}
else {
cout << "无法打开文件:" << filename << endl;
}
system("pause");
system("cls");
}
没啥好说的,借助父类指针数组,打印就完了,注意可以使用水平制表符来统一格式。
//显示职工信息
void WorkerManger::showinfo(abstractWorker* worker[]) {
cout << "当前共有 " << person_index << " 名职工" << endl;
cout << "职工信息如下:" << endl;
cout << "ID\t姓名\t等级\t岗位" << endl;
for (int i = 0; i < person_index; i++) {
cout << worker[i]->worker_ID << "\t" << worker[i]->worker_name << "\t" << worker[i]->level <<"\t"<<worker[i]->getDeptname() << endl;
}
system("pause");
system("cls");
}
不过这里最好建议用上面的读取文件的方式来显示,因为这样的话,即使退出了程序,内容也不会丢失,可以随时读取。
deleteWorker 函数的实现过程如下:
检查职工数组是否为空,如果为空则提示用户暂无职工记录并返回。
提示用户输入要删除的职工的ID号。
遍历职工数组,查找要删除的职工在数组中的下标。
如果未找到要删除的职工,则提示用户未找到该职工并返回。
如果找到要删除的职工,释放该职工对象的内存空间,将后面的职工对象向前移动,职工数量减一。
最后,将更新后的职工信息写入文件,并提示用户删除成功。
void WorkerManger::deleteworker(abstractWorker* worker[]) {
if (person_index == 0) {
cout << "暂无职工记录!" << endl;
return;
}
cout << "请输入要删除的职工ID:" << endl;
int id_num;
cin >> id_num;
int index = -1; // 要删除的职工在数组中的下标
for (int i = 0; i < person_index; i++) {
if (id_num==worker[i]->worker_ID) {
index = i;
break;
}
}
if (index == -1) {
cout << "未找到该职工!" << endl;
return;
}
delete worker[index]; // 释放要删除的职工对象的内存空间
for (int i = index; i < person_index - 1; i++) {
worker[i] = worker[i + 1]; // 将后面的职工对象向前移动
}
person_index--; // 职工数量减一
// 将更新后的职工信息写入文件
for (int i = 0; i < person_index; i++) {
ofs << worker[i]->worker_ID << "\t"
<< worker[i]->worker_name << "\t"
<< worker[i]->level << "\t"
<< worker[i]->getDeptname() << endl;
}
ofs.close();
cout << "删除成功!" << endl;
}
//修改职工信息
void WorkerManger::modifyWorker(abstractWorker* worker[]) {
if (person_index == 0) {
cout << "暂无职工记录!" << endl;
return;
}
cout << "请输入要修改的职工当前ID:" << endl;
int id_num;
cin >> id_num;
int index = -1; // 要修改的职工在数组中的下标
for (int i = 0; i < person_index; i++) {
if (id_num == worker[i]->worker_ID) {
index = i;
break;
}
}
if (index == -1) {
cout << "未找到该职工!" << endl;
return;
}
cout << "请输入修改后的职工姓名:" << endl;
string name;
cin >> name;
worker[index]->worker_name = name;
// 将更新后的职工信息写入文件
for (int i = 0; i < person_index; i++) {
ofs << worker[i]->worker_ID << "\t"
<< worker[i]->worker_name << "\t"
<< worker[i]->level << "\t"
<< worker[i]->getDeptname() << endl;
}
ofs.close();
cout << "修改成功!" << endl;
}
首先,根据用户输入的查找方式(ID号或姓名),提示用户输入相应的信息。
根据用户输入的信息,在职工数组中查找匹配的职工对象。
如果找到匹配的职工对象,输出职工的详细信息;如果未找到匹配的职工对象,输出未找到的提示信息。
具体的代码实现如下:
void WorkerManger::searchWorker(abstractWorker* worker[]) {
if (person_index == 0) {
cout << "暂无职工记录!" << endl;
return;
}
cout << "请选择查找方式:" << endl;
cout << "1. 根据ID号查找" << endl;
cout << "2. 根据姓名查找" << endl;
int choice;
cin >> choice;
if (choice == 1) {
cout << "请输入要查找的职工ID号:" << endl;
int id_num;
cin >> id_num;
bool found = false;
for (int i = 0; i < person_index; i++) {
if (id_num == worker[i]->worker_ID) {
found = true;
cout << "职工ID号:" << worker[i]->worker_ID << endl;
cout << "职工姓名:" << worker[i]->worker_name << endl;
cout << "职工岗位:" << worker[i]->getDeptname() << endl;
cout << "职工等级:" << worker[i]->worker_level << endl;
break;
}
}
if (!found) {
cout << "未找到该职工!" << endl;
}
} else if (choice == 2) {
cout << "请输入要查找的职工姓名:" << endl;
string name;
cin >> name;
bool found = false;
for (int i = 0; i < person_index; i++) {
if (name == worker[i]->worker_name) {
found = true;
cout << "职工ID号:" << worker[i]->worker_ID << endl;
cout << "职工姓名:" << worker[i]->worker_name << endl;
cout << "职工岗位:" << worker[i]->getDeptname() << endl;
cout << "职工等级:" << worker[i]->worker_level << endl;
break;
}
}
if (!found) {
cout << "未找到该职工!" << endl;
}
} else {
cout << "输入无效!" << endl;
}
}
思路:根据level等级来判断,1是员工,2是经理,3是老板
//实现功能:将员工、经理、老板三类分别打印其信息
void WorkerManger::printWorker(abstractWorker* worker[]) {
if (person_index == 0) {
cout << "暂无职工记录!" << endl;
return;
}
cout << "请选择查找岗位:1-员工 2-经理 3-老板" << endl;
int choice;
cin >> choice;
switch (choice) {
case 1:
cout << "员工信息:" << endl;
for (int i = 0; i < person_index; i++) {
//检索出level=1的各员工的下标,并将其信息进行打印
if (worker[i]->level == 1) {
cout << worker[i]->worker_ID << "\t" << worker[i]->worker_name << "\t"
<< worker[i]->level << "\t" << worker[i]->getDeptname() << endl;
}
}
break;
case 2:
cout << "经理信息:" << endl;
for (int i = 0; i < person_index; i++) {
//检索出level=1的各员工的下标,并将其信息进行打印
if (worker[i]->level == 2) {
cout << worker[i]->worker_ID << "\t" << worker[i]->worker_name << "\t"
<< worker[i]->level << "\t" << worker[i]->getDeptname() << endl;
}
}
break;
case 3:
cout << "老板信息:" << endl;
for (int i = 0; i < person_index; i++) {
//检索出level=1的各员工的下标,并将其信息进行打印
if (worker[i]->level == 3) {
cout << worker[i]->worker_ID << "\t" << worker[i]->worker_name << "\t"
<< worker[i]->level << "\t" << worker[i]->getDeptname() << endl;
}
}
break;
default:
cout << "无效的选项!" << endl;
break;
}
}
函数首先以覆盖模式打开文件,然后写入一个空字符串来清空文件内容。
void WorkerManger::clearFile() {
ofstream ofs(filename, ios::trunc); // 打开文件并以覆盖模式写入空字符串
if (ofs.is_open()) {
ofs << ""; // 写入空字符串
ofs.close();
cout << "文件已清空!" << endl;
}
else {
cout << "无法打开文件:" << filename << endl;
}
}
void WorkerManger::deleteworker(abstractWorker* worker[]) {
if (person_index == 0) {
cout << "暂无职工记录!" << endl;
return;
}
cout << "请输入要删除的职工ID:" << endl;
int id_num;
cin >> id_num;
int index = -1; // 要删除的职工在数组中的下标
for (int i = 0; i < person_index; i++) {
if (id_num==worker[i]->worker_ID) {
index = i;
break;
}
}
if (index == -1) {
cout << "未找到该职工!" << endl;
return;
}
delete worker[index]; // 释放要删除的职工对象的内存空间
for (int i = index; i < person_index - 1; i++) {
worker[i] = worker[i + 1]; // 将后面的职工对象向前移动
}
person_index--; // 职工数量减一
// 先清空文件内容
ofs.open("worker.txt", ios::out | ios::trunc);
ofs.close();
// 将更新后的职工信息写入文件
ofs.open("worker.txt", ios::out | ios::app);
for (int i = 0; i < person_index; i++) {
ofs << worker[i]->worker_ID << "\t"
<< worker[i]->worker_name << "\t"
<< worker[i]->level << "\t"
<< worker[i]->getDeptname() << endl;
}
ofs.close();
cout << "删除成功!" << endl;
}
//修改职工信息
void WorkerManger::modifyWorker(abstractWorker* worker[]) {
if (person_index == 0) {
cout << "暂无职工记录!" << endl;
return;
}
cout << "请输入要修改的职工当前ID:" << endl;
int id_num;
cin >> id_num;
int index = -1; // 要修改的职工在数组中的下标
for (int i = 0; i < person_index; i++) {
if (id_num == worker[i]->worker_ID) {
index = i;
break;
}
}
if (index == -1) {
cout << "未找到该职工!" << endl;
return;
}
cout << "请输入修改后的职工姓名:" << endl;
string name;
cin >> name;
worker[index]->worker_name = name;
// 先清空文件内容
ofs.open("worker.txt", ios::out | ios::trunc);
ofs.close();
// 将更新后的职工信息写入文件
ofs.open("worker.txt", ios::app);
for (int i = 0; i < person_index; i++) {
ofs << worker[i]->worker_ID << "\t"
<< worker[i]->worker_name << "\t"
<< worker[i]->level << "\t"
<< worker[i]->getDeptname() << endl;
}
cout << "修改成功!" << endl;
}
目前没有解决办法,暂时挂在这里。。。。。。