The second case of dark horse C + + Video: employee management system

The second case of dark horse C + + Video: employee management system

I Requirement analysis

  • Employees are divided into three categories: ordinary employees, managers and bosses. They all have common attributes of employee ID, name and responsibility type, as well as common functions to display employee information. Therefore, you can take employee class as abstract class, ordinary employee class, manager class and boss class as subclasses of employees, and use polymorphism to realize different functions.

  • An employee management class is used to realize the specific function, and the Employee class contains the number of employees. A pointer array is used to maintain the employee information, and a bool variable is used to judge whether the file required to be read is empty.

  • The next step is the implementation of specific function functions.

II code analysis

1. Use array to maintain employee information

Worker** workerArr = new Worker*[worker_num];

Similar to a workerArr array, the array stores the pointer variable of the worker, pointing to the worker space specifically opened up in the heap, so the workerArr here is a secondary pointer.

2. Initialization of employee management class

//Constructor. When constructing the constructor, you also need to judge whether the file exists
WorkerManager::WorkerManager()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	char ch;

	//Initialize when file does not exist
	if (!ifs.is_open())
	{
		this->fileIsEmpty = true;
		this->workerArr = NULL;
		this->worker_num = 0;
		//Cout < < file does not exist < < endl; (for testing)
		ifs.close(); 
		return;
	}
	
	//Initialize when the file exists but is empty
	ifs >> ch;
	if (ifs.eof())
	{
		this->fileIsEmpty = true;
		this->workerArr = NULL;
		this->worker_num = 0;
		//Cout < < file is empty < < endl; (for testing)
		ifs.close();
		return;
	}

	//Initialize when the file exists and is not empty
	this->fileIsEmpty = false;
	this->worker_num = getWorkerNum();
	this->workerArr = new Worker * [this->worker_num];
	initialize();
	//Test code
	//for (int i = 0; i < worker_num; i++)
	//{
	//	cout << workerArr[i]->m_ID << "\t"
	//		<< workerArr[i]->m_name << "\t"
	//		<< workerArr[i]->getDeptName() << endl;
	//}
}
void WorkerManager::initialize()
{
	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;
		switch (deptID)
		{
		case 0:
			worker = new Employee(id, name);
			this->workerArr[index] = worker;
			break;
		case 1:
			worker = new Management(id, name);
			this->workerArr[index] = worker;
			break;
		case 2:
			worker = new Boss(id, name);
			this->workerArr[index] = worker;
			break;
		}
		index++;
	}
}

The initialization of employee management class is troublesome. There are three situations: file does not exist, file exists but is empty, and file exists and is not empty. It needs to be judged by the object of the file input stream ifstream, and the object can be constructed in three cases. Use the fileIsEmpty variable to judge the file condition.

3. Add some codes in the employee function

int newNum = this->worker_num + num;
	Worker** newSpace = new Worker * [newNum];

	//Transfer the original pointer array to the new array
	if (workerArr != NULL)
	{
		for (int i = 0; i < worker_num; i++)
		{
			newSpace[i] = workerArr[i];
		}
	}

Before adding, calculate the number of employees after adding employees, then build a new pointer array through the new number of employees, and copy the original pointer array to the new array.

delete[] workerArr;
	workerArr = newSpace;
	worker_num = newNum;
	save();
	if (fileIsEmpty == true)
	{
		fileIsEmpty = false;
	}

After adding employees, don't forget to delete the original pointer array to free up space.

4. Destructor

WorkerManager::~WorkerManager()
{
	for (int i = 0; i < worker_num; i++)
	{
		delete[] workerArr[i];
		workerArr[i] = NULL;
		cout << "Delete succeeded" << endl;
	}
}

III Code display

Employee management code:

#include"WorkerManager.h"

//Constructor. When constructing the constructor, you also need to judge whether the file exists
WorkerManager::WorkerManager()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	char ch;

	//Initialize when file does not exist
	if (!ifs.is_open())
	{
		this->fileIsEmpty = true;
		this->workerArr = NULL;
		this->worker_num = 0;
		//Cout < < file does not exist < < endl; (for testing)
		ifs.close(); 
		return;
	}
	
	//Initialize when the file exists but is empty
	ifs >> ch;
	if (ifs.eof())
	{
		this->fileIsEmpty = true;
		this->workerArr = NULL;
		this->worker_num = 0;
		//Cout < < file is empty < < endl; (for testing)
		ifs.close();
		return;
	}

	//Initialize when the file exists and is not empty
	this->fileIsEmpty = false;
	this->worker_num = getWorkerNum();
	this->workerArr = new Worker * [this->worker_num];
	initialize();
	//Test code
	//for (int i = 0; i < worker_num; i++)
	//{
	//	cout << workerArr[i]->m_ID << "\t"
	//		<< workerArr[i]->m_name << "\t"
	//		<< workerArr[i]->getDeptName() << endl;
	//}
}

//Destructor
WorkerManager::~WorkerManager()
{
	for (int i = 0; i < worker_num; i++)
	{
		delete[] workerArr[i];
		workerArr[i] = NULL;
		cout << "Delete succeeded" << endl;
	}
}

//Interface display
void WorkerManager::showSelection()
{
	cout << "--------------------------------------------------------" << endl;
	cout << "--------------------Employee management system------------------------" << endl;
	cout << "--------------------1,Add employee information---------------------" << endl;
	cout << "--------------------2,Display employee information---------------------" << endl;
	cout << "--------------------3,Delete employee information---------------------" << endl;
	cout << "--------------------4,Modify employee information---------------------" << endl;
	cout << "--------------------5,Find employee information---------------------" << endl;
	cout << "--------------------6,Sort by number---------------------" << endl;
	cout << "--------------------7,Empty all documents---------------------" << endl;
	cout << "--------------------8,Exit management program---------------------" << endl;
	cout << "--------------------------------------------------------" << endl;
}

//The first method: add employees and write files
void WorkerManager::addWorker()
{
	cout << "Please select the number of employees to add" << endl;
	int num;
	cin >> num;
	int newNum = this->worker_num + num;
	Worker** newSpace = new Worker * [newNum];

	//Transfer the original pointer array to the new array
	if (workerArr != NULL)
	{
		for (int i = 0; i < worker_num; i++)
		{
			newSpace[i] = workerArr[i];
		}
	}

	//Add new employee
	for (int i = 0; i < num; i++)
	{
		cout << endl;
		cout << "Add section below" << i + 1 << "Employees" << endl;
		int id;
		cout << "Please enter the employee's ID" << endl;
		cin >> id;

		string name;
		cout << "Please enter the employee's name" << endl;
		cin >> name;

		int selection;
		cout << "Please enter a number to select the position of the employee:" << endl;
		cout << "1:Ordinary staff" << endl;
		cout << "2:manager" << endl;
		cout << "3:CEO" << endl;
		cin >> selection;

		Worker* worker;
		switch (selection)
		{
		case 1:
			worker = new Employee(id, name);
			newSpace[worker_num + i] = worker;
			break;
		case 2:
			worker = new Management(id, name);
			newSpace[worker_num + i] = worker;
			break;
		case 3:
			worker = new Boss(id, name);
			newSpace[worker_num + i] = worker;
			break;
		default:
			cout << "Wrong choice" << endl;
			break;
		}
	}
	delete[] workerArr;
	workerArr = newSpace;
	worker_num = newNum;
	save();
	if (fileIsEmpty == true)
	{
		fileIsEmpty = false;
	}
	system("pause");
	system("cls");
}

//The second method: display the employee information in the current list
void WorkerManager::display()
{
	if (fileIsEmpty == true)
	{
		cout << "The file does not exist or is empty" << endl;
	}
	else
	{
		for (int i = 0; i < worker_num; i++)
		{
			workerArr[i]->showInfo();
		}
	}

	system("pause");
	system("cls");
}

//The third method: delete employee
void WorkerManager::deleteWorker()
{
	if (fileIsEmpty == true)
	{
		cout << "The file does not exist or is empty" << endl;
	}
	else
	{
		cout << "Please enter the employee number you want to delete" << endl;
		int deleteNum;
		cin >> deleteNum;

		if (isExist(deleteNum) == -1)
		{
			cout << "No one was found" << endl;
		}
		else
		{
			int pointer = isExist(deleteNum);
			for (; pointer < worker_num - 1; pointer++)
			{
				workerArr[pointer] = workerArr[pointer + 1];
			}
			workerArr[worker_num - 1] = NULL;
			worker_num--;
			cout << "Delete succeeded" << endl;
		}
		save();
	}
	system("pause");
	system("cls");
}

//The fourth method: modify employee information
void WorkerManager::modMessage()
{
	if (fileIsEmpty == true)
	{
		cout << "The file does not exist or is empty" << endl;
	}
	else
	{
		int selection;
		cout << "Please enter the employee number to modify" << endl;
		cin >> selection;
		int pointer = isExist(selection);
		if (pointer == -1)
		{
			cout << "No one was found" << endl;
		}
		else
		{
			cout << "Find the employee and enter the modified information below" << endl;
			int tempID;
			string tempName;
			int tempDeptID;
			cout << "Please enter employee number" << endl;
			cin >> tempID;
			cout << "Please enter employee name" << endl;
			cin >> tempName;
			cout << "Please select employee position" << endl;
			cout << "1.Ordinary staff" << endl;
			cout << "2.manager" << endl;
			cout << "3.CEO" << endl;
			int tempSelection;
			cin >> tempSelection;

			Worker* worker;
			switch (tempSelection)
			{
			case 1:
				worker = new Employee(tempID, tempName);
				workerArr[pointer] = worker;
				break;
			case 2:
				worker = new Management(tempID, tempName);
				workerArr[pointer] = worker;
				break;
			case 3:
				worker = new Boss(tempID, tempName);
				workerArr[pointer] = worker;
				break;
			default:
				cout << "Wrong choice" << endl;
				break;
			}
			cout << "Modified successfully" << endl;
		}
		save();
	}
	system("pause");
	system("cls");
}

//The fifth method: find employees by employee number or name
void WorkerManager::seekWorker()
{
	if (fileIsEmpty == true)
	{
		cout << "The file does not exist or is empty" << endl;
	}
	else
	{
		cout << "Please select your search method" << endl;
		cout << "1.Find by employee number" << endl;
		cout << "2.Find by employee name" << endl;
		int selection = 0;
		cin >> selection;
		switch (selection)
		{
		case 1:
		{
			cout << "Please select the employee number you want to find" << endl;
			int searchID;
			cin >> searchID;
			int pointer = isExist(searchID);
			if (pointer == -1)
			{
				cout << "No one was found" << endl;
				system("pause");
				system("cls");
				return;
			}
			else
			{
				cout << "Find employee information as follows" << endl;
				workerArr[pointer]->showInfo();
				system("pause");
				system("cls");
				return;
			}
		}
		case 2:
		{
			cout << "Enter the name of the employee you want to find" << endl;
			string searchName;
			cin >> searchName;
			bool isExist = false;
			for (int i = 0; i < worker_num; i++)
			{
				if (workerArr[i]->m_name == searchName)
				{
					workerArr[i]->showInfo();
					isExist = true;
				}
			}
			if (isExist == false)
			{
				cout << "No one was found" << endl;
				system("pause");
				system("cls");
				return;
			}
			system("pause");
			system("cls");
			return;
		}
		default:
			cout << "Incorrect input" << endl;
			break;
		}
	}
	system("pause");
	system("cls");
}

//The sixth method: sort the employees in the document by employee number
void WorkerManager::sortByID()
{
	if (fileIsEmpty == true)
	{
		cout << "The file does not exist or is empty" << endl;
	}
	else
	{
		cout << "Please select your sorting method" << endl;
		cout << "1.Ascending by number" << endl;
		cout << "2.Descending by number" << endl;
		int selection = 0;
		cin >> selection;
		if (selection == 1)
		{
			for (int i = 0; i < worker_num; i++)
			{
				for (int j = i + 1; j < worker_num; j++)
				{
					if (workerArr[i]->m_ID > workerArr[j]->m_ID)
					{
						Worker* tempWorker;
						tempWorker = workerArr[i];
						workerArr[i] = workerArr[j];
						workerArr[j] = tempWorker;
					}
				}
			}
			cout << "Sorting succeeded" << endl;
			save();
		}
		else if (selection == 2)
		{
			for (int i = 0; i < worker_num; i++)
			{
				for (int j = i + 1; j < worker_num; j++)
				{
					if (workerArr[i]->m_ID < workerArr[j]->m_ID)
					{
						Worker* tempWorker;
						tempWorker = workerArr[i];
						workerArr[i] = workerArr[j];
						workerArr[j] = tempWorker;
					}
				}
			}
			cout << "Sorting succeeded" << endl;
			save();
		}
		else
		{
			cout << "Incorrect input" << endl;
		}
	}
	system("pause");
	system("cls");
}

//Seventh method: empty the file
void WorkerManager::emptyFile()
{
	if (fileIsEmpty == true)
	{
		cout << "The file does not exist or is empty" << endl;
	}
	else
	{
		cout << "Are you sure you want to empty the file?" << endl;
		cout << "Input: Y/N" << endl;
		char selection;
		cin >> selection;
		if (selection == 'Y' || selection == 'y')
		{
			ofstream ofs;
			ofs.open(FILENAME, ios::trunc);
			ofs.close();

			if (workerArr != NULL)
			{
				for (int i = 0; i < worker_num; i++)
				{
					delete workerArr[i];
					workerArr[i] = NULL;
				}
			}
			delete[] workerArr;
			workerArr = NULL;
			fileIsEmpty = true;
			cout << "Empty successfully" << endl;
		}
		else if (selection == 'N' || selection == 'n')
		{
			cout << "Do not empty" << endl;
		}
		else
		{
			cout << "Incorrect input" << endl;
		}
		system("pause");
		system("cls");
	}
}

//The eighth method: exit the program
void WorkerManager::exitProcedure()
{
	cout << "Welcome to use next time" << endl;
	exit(0);
}

//Sub method: save the current worker array information to the file
void WorkerManager::save()
{
	ofstream ofs;
	ofs.open(FILENAME, ios::out);

	for (int i = 0; i < worker_num; i++)
	{
		ofs << workerArr[i]->m_ID << " "
			<< workerArr[i]->m_name << " "
			<< workerArr[i]->dept_ID << endl;
	}
	ofs.close();
}

//Submethods: help initialization
void WorkerManager::initialize()
{
	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;
		switch (deptID)
		{
		case 0:
			worker = new Employee(id, name);
			this->workerArr[index] = worker;
			break;
		case 1:
			worker = new Management(id, name);
			this->workerArr[index] = worker;
			break;
		case 2:
			worker = new Boss(id, name);
			this->workerArr[index] = worker;
			break;
		}
		index++;
	}
}

//Sub method: get the number of employees in the file
int WorkerManager::getWorkerNum()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);

	int id;
	string name;
	int deptID;
	this->worker_num = 0;

	while (ifs >> id && ifs >> name && ifs >> deptID)
	{
		this->worker_num++;
	}

	return this->worker_num;
}

//Sub method: judge the entered employee number and find out whether this person exists
int WorkerManager::isExist(int searchID)
{
	for (int i = 0; i < worker_num; i++)
	{
		if (workerArr[i]->m_ID == searchID)
		{
			return i;
		}
	}
	return -1;
}

Abstract Employee class code:

class Worker
{
public:
	int m_ID;//Employee ID
	int dept_ID;//Employee's position number
	string m_name;//Employee name

	virtual void showInfo() = 0;//Display employee information
	virtual string getDeptName() = 0;//Get employee position name
};

Main function code:

#include<iostream>
#include"WorkerManager.h"
using namespace std;

int main()
{
	WorkerManager wm;

	while (true)
	{
		wm.showSelection();

		cout << "Please enter your action" << endl;
		int selection;
		cin >> selection;

		switch (selection)
		{
		case 1://Add employee information
			wm.addWorker();
			break;

		case 2://Display employee information
			wm.display();
			break;

		case 3://Delete employee information
			wm.deleteWorker();
			break;

		case 4://Modify employee information
			wm.modMessage();
			break;

		case 5://Find employee information
			wm.seekWorker();
			break;

		case 6://Sort by number
			wm.sortByID();
			break;

		case 7://Empty all documents
			wm.emptyFile();
			break;

		case 8://Exit management program
			wm.exitProcedure();
			break;

		default:
		{
			cout << "Incorrect input" << endl;
			exit(0);
		}
			break;
		}
	}
	system("pause");
	return 0;
}

The three employee codes are not displayed one by one.

Added by uramagget on Wed, 12 Jan 2022 09:41:42 +0200