Тема: Як зберегти у файлі (файлах) об'єкти двох взаємозв'язаних класів?
Необхідно записати у файл об'єкти Worker (і, скоріше за все Department): (взаємозв'язок класів у темі - http://replace.org.ua/topic/6347/, як покращити - не знаю, згідно завдання може і ніяк)
class Person
{
protected:
string surname;
string name;
string birthday;
string city;
string street;
int house_number;
int flat_number;
string phone_number;
string education;
};
class Worker: public Person
{
int account_number_salary;
Department department;
Position position;
Project projects[NUMBER_LAST_PROJECTS];
int current_number_projects;
double experience;
double total_projects_cost;
};
class Department
{
string name;
Worker *workers;
int number_workers;
string major_department_name;
double amount_prize;
string *positions;
int number_positions;
};
В попередньому варіанті задачі я зробила ось так:
▼Прихований текст
/* Предметна область - відділ кадрів фірми.
Розв'язувані задачі - облік співробітників. Реалізувати наступні сервіси:
-Заповнення бази даних
-Перегляд даних про всіх співробітників
-Доповнення бази даних новим співробітником
-Видалення із бази даних вказаного співробітника
-Упорядкування: співробітники по відділах, по посадах
-Пошук: всі дані про співробітника з певним ПІБ; як подзвонити співробітникові УУ
-Вибірка: співробітники відділу NN
-Обчислення: кількість співробітників у відділі NN; фонд заробітної плати по відділах
-Корекція: видалення зведень про звільненого співробітника;
переведення співробітника з відділу ХХ у відділ УУ
-Табличний звіт: список співробітників по відділах, підсумок - фонд зарплати кожного відділу
і загальний фонд по фірмі
Додаткові вимоги: ПІБ співробітника не повинні бути порожніми значеннями, а табельний номер співробітника
повинний бути унікальним.
Для обробки даних скористатися динамічним масивом покажчиків на структури відповідного типу. */
#include <iostream>
#include <iomanip>
#include <fstream>
#include <windows.h>
#include <string>
#include <conio.h>
using namespace std;
struct PersonalInfo
{
string surname;
string name;
string birthday;
struct Adress
{
string city;
string street;
int house_number;
int flat_number;
} adress;
string phone_number;
string education;
};
struct Worker
{
int ID;
PersonalInfo personal;
string department_name;
string position;
int salary;
int experience;
string work_status;
};
struct Department
{
string dep_name;
int funds;
Worker *workers;
int number_workers;
};
// Log info for easy debug
void log(string message)
{
ofstream f("hr_department.log", ios::out | ios::app);
f << message << "\n";
f.close();
}
void createDepartments(Department *&departments, int &number_departments)
{
if (number_departments == 0)
number_departments = 1;
departments = new Department[number_departments];
}
void addDepartment(Department *&departments, int &number_departments, string name_departments)
{
if (departments == NULL)
{
createDepartments(departments, number_departments);
departments[number_departments - 1].dep_name = name_departments;
for (int i = 0; i < number_departments; ++i)
{
departments[i].number_workers = 1;
for (int j = 0; j < departments[i].number_workers; ++j)
departments[i].workers = new Worker[departments[i].number_workers];
}
}
else
{
Department *new_departments = new Department[number_departments + 1];
for (int i = 0; i < number_departments; ++i)
new_departments[i] = departments[i];
new_departments[number_departments].dep_name = name_departments;
if (departments != NULL)
delete[]departments;
departments = new_departments;
++number_departments;
}
}
void addWorkerInDepartment(Department *&departments, int &number_departments, Worker worker)
{
if (departments == NULL)
{
addDepartment(departments, number_departments, worker.department_name);
departments[number_departments - 1].workers[departments[number_departments - 1].number_workers - 1] = worker;
}
else
{
int i = 0;
while (i < number_departments && departments[i].dep_name != worker.department_name)
++i;
if (i < number_departments)
{
Worker *temp_workers = new Worker[departments[i].number_workers + 1];
for (int j = 0; j < departments[i].number_workers; ++j)
temp_workers[j] = departments[i].workers[j];
temp_workers[departments[i].number_workers] = worker;
delete[]departments[i].workers;
departments[i].workers = temp_workers;
++departments[i].number_workers;
}
else
{
addDepartment(departments, number_departments, worker.department_name);
departments[i].number_workers = 1;
departments[i].workers = new Worker[departments[i].number_workers];
departments[i].workers[departments[i].number_workers - 1] = worker;
}
}
}
void deleteWorkerFromTheDepartment(Department *&departments, int &number_departments, Worker worker)
{
if (departments == NULL)
cout << "Database is empty\n";
else
{
int i = 0;
while (i < number_departments && departments[i].dep_name != worker.department_name)
++i;
if (i < number_departments)
{
int k = 0;
while (k < departments[i].number_workers && departments[i].workers[k].ID != worker.ID)
++k;
if (k < departments[i].number_workers)
{
Worker *temp_workers = new Worker[departments[i].number_workers - 1];
for (int j = 0; j < k; ++j)
temp_workers[j] = departments[i].workers[j];
for (int j = k; j < departments[i].number_workers - 1; ++j)
temp_workers[j] = departments[i].workers[j + 1];
delete[]departments[i].workers;
departments[i].workers = temp_workers;
--departments[i].number_workers;
}
}
}
}
bool SetWindow(int Width, int Height)
{
_COORD coord;
coord.X = Width;
coord.Y = Height;
_SMALL_RECT Rect;
Rect.Top = 0;
Rect.Left = 0;
Rect.Bottom = Height - 1;
Rect.Right = Width - 1;
// Get handle of the standard output
HANDLE Handle = GetStdHandle(STD_OUTPUT_HANDLE);
if (Handle == NULL)
{
cout << "Failure in getting the handle\n" << GetLastError();
return FALSE;
}
// Set screen buffer size to that specified in coord
if (!SetConsoleScreenBufferSize(Handle, coord))
{
cout << "Failure in setting buffer size\n" << GetLastError();
return FALSE;
}
// Set the window size to that specified in Rect
if (!SetConsoleWindowInfo(Handle, TRUE, &Rect))
{
cout << "Failure in setting window size\n" << GetLastError();
return FALSE;
}
return TRUE;
}
struct ITEM{
int x;
int y;
string name_menu;
};
// global variable
enum key { UP = 72, DOWN = 80, ENTER = 13, ESCAPE = 27 };
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbInfo;
SMALL_RECT consolRect;
COORD curspos = { 0, 1 };
WORD workWindowAttributes = 95;
WORD inactiveItemAttributes = 71;
WORD activeItemAttributes = 207;
void gotoxy(int x, int y)
{
COORD cursorPos = { x, y };
SetConsoleCursorPosition(hStdOut, cursorPos);
SetConsoleCursorPosition(hStdOut, { x, y });
}
void getCursorPosition()
{
GetConsoleScreenBufferInfo(hStdOut, &csbInfo);
curspos = csbInfo.dwCursorPosition;
}
void showCursor(bool visible)
{
CONSOLE_CURSOR_INFO ccInfo;
ccInfo.bVisible = visible;
ccInfo.dwSize = 20;
SetConsoleCursorInfo(hStdOut, &ccInfo);
}
//TODO: color text, move to keys in the menu
void writeToFile(string file_name, Worker *workers, int number_workers)
{
ofstream f_out(file_name, ios_base::out | ios_base::binary);
if (!f_out)
cout << "Can not open file to write\n";
f_out.write((char *)&number_workers, sizeof(number_workers));
for (int i = 0; i < number_workers; ++i)
{
int ser = workers[i].salary;
f_out.write((char *)&ser, sizeof(ser));
ser = workers[i].personal.adress.house_number;
f_out.write((char *)&ser, sizeof(ser));
ser = workers[i].personal.adress.flat_number;
f_out.write((char *)&ser, sizeof(ser));
ser = workers[i].experience;
f_out.write((char *)&ser, sizeof(ser));
ser = workers[i].personal.surname.length();
f_out.write((char *)&ser, sizeof(ser));
f_out.write(workers[i].personal.surname.c_str(), ser);
ser = workers[i].personal.name.length();
f_out.write((char *)&ser, sizeof(ser));
f_out.write(workers[i].personal.name.c_str(), ser);
ser = workers[i].personal.birthday.length();
f_out.write((char *)&ser, sizeof(ser));
f_out.write(workers[i].personal.birthday.c_str(), ser);
ser = workers[i].personal.phone_number.length();
f_out.write((char *)&ser, sizeof(ser));
f_out.write(workers[i].personal.phone_number.c_str(), ser);
ser = workers[i].personal.education.length();
f_out.write((char *)&ser, sizeof(ser));
f_out.write(workers[i].personal.education.c_str(), ser);
ser = workers[i].personal.adress.city.length();
f_out.write((char *)&ser, sizeof(ser));
f_out.write(workers[i].personal.adress.city.c_str(), ser);
ser = workers[i].personal.adress.street.length();
f_out.write((char *)&ser, sizeof(ser));
f_out.write(workers[i].personal.adress.street.c_str(), ser);
ser = workers[i].ID;
f_out.write((char *)&ser, sizeof(ser));
ser = workers[i].department_name.length();
f_out.write((char *)&ser, sizeof(ser));
f_out.write(workers[i].department_name.c_str(), ser);
ser = workers[i].position.length();
f_out.write((char *)&ser, sizeof(ser));
f_out.write(workers[i].position.c_str(), ser);
ser = workers[i].work_status.length();
f_out.write((char *)&ser, sizeof(ser));
f_out.write(workers[i].work_status.c_str(), ser);
}
cout << "Data is written in the file successfully\n";
f_out.close();
}
void loadFromFile(string file_name, Worker *&workers, int &number_workers, Department *&departments, int &number_departments)
{
ifstream f_in(file_name, ios_base::binary);
if (!f_in)
cout << "Can not open file to read\n";
else
{
f_in.read((char *)&number_workers, sizeof(number_workers));
Worker *new_workers = new Worker[number_workers];
char *temp_str;
int ser;
for (int i = 0; i < number_workers; ++i)
{
f_in.read((char *)&ser, sizeof(ser));
new_workers[i].salary = ser;
f_in.read((char *)&ser, sizeof(ser));
new_workers[i].personal.adress.house_number = ser;
f_in.read((char *)&ser, sizeof(ser));
new_workers[i].personal.adress.flat_number = ser;
f_in.read((char *)&ser, sizeof(ser));
new_workers[i].experience = ser;
f_in.read((char *)&ser, sizeof(ser));
temp_str = new char[ser + 1];
memset(temp_str, 0, ser + 1);
f_in.read(temp_str, ser);
new_workers[i].personal.surname.assign(temp_str);
delete[]temp_str;
f_in.read((char *)&ser, sizeof(ser));
temp_str = new char[ser + 1];
memset(temp_str, 0, ser + 1);
f_in.read(temp_str, ser);
new_workers[i].personal.name.assign(temp_str);
delete[]temp_str;
f_in.read((char *)&ser, sizeof(ser));
temp_str = new char[ser + 1];
memset(temp_str, 0, ser + 1);
f_in.read(temp_str, ser);
new_workers[i].personal.birthday.assign(temp_str);
delete[]temp_str;
f_in.read((char *)&ser, sizeof(ser));
temp_str = new char[ser + 1];
memset(temp_str, 0, ser + 1);
f_in.read(temp_str, ser);
new_workers[i].personal.phone_number.assign(temp_str);
delete[]temp_str;
f_in.read((char *)&ser, sizeof(ser));
temp_str = new char[ser + 1];
memset(temp_str, 0, ser + 1);
f_in.read(temp_str, ser);
new_workers[i].personal.education.assign(temp_str);
delete[]temp_str;
f_in.read((char *)&ser, sizeof(ser));
temp_str = new char[ser + 1];
memset(temp_str, 0, ser + 1);
f_in.read(temp_str, ser);
new_workers[i].personal.adress.city.assign(temp_str);
delete[]temp_str;
f_in.read((char *)&ser, sizeof(ser));
temp_str = new char[ser + 1];
memset(temp_str, 0, ser + 1);
f_in.read(temp_str, ser);
new_workers[i].personal.adress.street.assign(temp_str);
delete[]temp_str;
f_in.read((char *)&ser, sizeof(ser));
new_workers[i].ID = ser;
f_in.read((char *)&ser, sizeof(ser));
temp_str = new char[ser + 1];
memset(temp_str, 0, ser + 1);
f_in.read(temp_str, ser);
new_workers[i].department_name.assign(temp_str);
delete[]temp_str;
f_in.read((char *)&ser, sizeof(ser));
temp_str = new char[ser + 1];
memset(temp_str, 0, ser + 1);
f_in.read(temp_str, ser);
new_workers[i].position.assign(temp_str);
delete[]temp_str;
f_in.read((char *)&ser, sizeof(ser));
temp_str = new char[ser + 1];
memset(temp_str, 0, ser + 1);
f_in.read(temp_str, ser);
new_workers[i].work_status.assign(temp_str);
delete[]temp_str;
addWorkerInDepartment(departments, number_departments, new_workers[i]);
}
workers = new_workers;
cout << "Data loaded successfully\n";
}
f_in.close();
}
bool validInputPhoneNumber(const string phone)
{
int i = 0;
int phone_length = phone.length();
while (i < phone_length)
{
if (!(isdigit(phone[i]) || phone[i] == '-'))
return false;
++i;
}
return true;
}
bool validInputNameSurname(const string name)
{
if (name == " ")
return false;
int i = 0;
int name_length = name.length();
while (i < name_length)
{
if (!(isalpha(name[i])))
return false;
++i;
}
return true;
}
bool validInputString(const string str)
{
if (str == " ")
return false;
return true;
}
bool validInputNumber(const int records)
{
if (records >= 1)
return true;
else
return false;
}
void getDayMonthYear(string str, int &day, int &month, int &year)
{
int pos_day = str.find('.');
if (pos_day != string::npos)
for (int i = 0; i < pos_day; ++i)
day = stoi(str);
int pos_month = str.find('.', pos_day + 1);
if (pos_month != string::npos)
for (int i = pos_day + 1; i < pos_month; ++i)
month = stoi(str);
int length = str.length();
for (int i = pos_month + 1; i <length; ++i)
year = stoi(str);
}
bool isLeapYear(unsigned int year)
{
return !(year % 400) || (!(year % 4) && (year % 100));
}
bool validBirthday(string str)
{
if (str == "")
return false;
int i = 0;
int length = str.length();
while (i < length)
{
if (!(isdigit(str[i]) || '.'))
return false;
++i;
}
int day, month, year;
getDayMonthYear(str, day, month, year);
if (year < 1 || month < 1 || day < 1)
return false;
if (month == 2)
{
if (isLeapYear(year))
{
if (day <= 29)
return true;
}
else if (day <= 28)
return true;
}
switch (month)
{
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
if (day <= 31)
return true;
break;
case 4: case 6: case 9: case 11:
if (day <= 30)
return true;
break;
}
return false;
}
//TODO: VALID BIRTHDAY
void inputWorkerRecord(Worker &worker, int index)
{
cin.ignore(255, '\n');
do{
cout << "Enter surname: ";
getline(cin, worker.personal.surname);
} while (!validInputNameSurname(worker.personal.surname));
do{
cout << "Enter name: ";
getline(cin, worker.personal.name);
} while (!validInputNameSurname(worker.personal.name));
do{
cout << "Enter birthday (dd.mm.yyyy): ";
getline(cin, worker.personal.birthday);
} while (!validBirthday(worker.personal.birthday));
do{
cout << "Enter city: ";
getline(cin, worker.personal.adress.city);
} while (!validInputString(worker.personal.adress.city));
do{
cout << "Enter street: ";
getline(cin, worker.personal.adress.street);
} while (!validInputString(worker.personal.adress.street));
do{
cout << "Enter the house number: ";
cin >> worker.personal.adress.house_number;
} while (!worker.personal.adress.house_number);
do{
cout << "Enter the flat number: ";
cin >> worker.personal.adress.flat_number;
} while (!worker.personal.adress.flat_number);
cin.ignore(255, '\n');
do{
cout << "Enter phone number: ";
getline(cin, worker.personal.phone_number);
} while (!validInputPhoneNumber(worker.personal.phone_number));
do{
cout << "Enter education: ";
getline(cin, worker.personal.education);
} while (!validInputString(worker.personal.education));
do{
cout << "In which department works: ";
getline(cin, worker.department_name);
} while (!validInputString(worker.department_name));
do{
cout << "In which position: ";
getline(cin, worker.position);
} while (!validInputString(worker.position));
do{
cout << "What salary: ";
cin >> worker.salary;
} while (!validInputNumber(worker.salary));
do{
cout << "What experience: ";
cin >> worker.experience;
} while (!validInputNumber(worker.experience));
cin.ignore(255, '\n');
do{
cout << "What is the status of work ( fired or work): ";
getline(cin, worker.work_status);
} while (!validInputString(worker.work_status));
worker.ID = index +1;
}
Worker *createNewBaseWorker(int &number_workers, Department *&departments, int &number_departments)
{
cout << "Enter the number of workers: ";
cin >> number_workers;
if (number_workers == 0)
number_workers = 1;
Worker *temp = new Worker[number_workers];
for (int i = 0; i < number_workers; ++i)
{
inputWorkerRecord(temp[i], i);
addWorkerInDepartment(departments, number_departments, temp[i]);
}
return temp;
}
int maxID(const Worker *workers, int &number_workers)
{
int max = workers[0].ID;
for (int i = 1; i < number_workers; ++i)
if (workers[i].ID > max)
max = workers[i].ID;
return max;
}
void addRecord(Worker *&workers, int &number_workers, Department *&departments, int &number_departments)
{
if (workers == NULL)
workers = createNewBaseWorker(number_workers, departments, number_departments);
else
{
Worker *new_workers = new Worker[number_workers + 1];
for (int i = 0; i < number_workers; ++i)
new_workers[i] = workers[i];
delete[]workers;
workers = new_workers;
inputWorkerRecord(workers[number_workers], maxID(workers, number_workers));
addWorkerInDepartment(departments, number_departments, workers[number_workers]);
++number_workers;
}
}
void headPrintRecord()
{
cout << "ID" << setw(8) << "Name " << setw(10) << "Surname " << setw(11) << "Birthday"<< setw(15) << "Phone number" << setw(8);
cout << "City" << setw(12) << "Street" << setw(9) << "House" << setw(8) << "Flat" << setw(8);
cout << "Depart." << setw(10) << "Position" << setw(8) << "Exper." << setw(8) << "Salary" << setw(15) << "Work status\n";
cout << "----------------------------------------------------------------------------------------------------------------------------------\n";
}
void printRecord(const Worker worker)
{
cout << worker.ID << setw(10) << worker.personal.name << setw(11) << worker.personal.surname << setw(9) << worker.personal.birthday << setw(15) << worker.personal.phone_number << setw(10);
cout << worker.personal.adress.city << setw(12) << worker.personal.adress.street << setw(8) << worker.personal.adress.house_number << setw(6) << worker.personal.adress.flat_number << setw(10);
cout << worker.department_name << setw(10) << worker.position << setw(8) << worker.experience << setw(8) << worker.salary << setw(10) << worker.work_status << "\n";
}
void showAllWorkers(const Worker *workers, int number_workers)
{
if (workers == NULL)
cout << "Database is empty\n";
else
{
headPrintRecord();
for (int i = 0; i < number_workers; ++i)
{
cout << workers[i].ID << setw(10) << workers[i].personal.name << setw(11) << workers[i].personal.surname << setw(9)<< workers[i].personal.birthday << setw(15) << workers[i].personal.phone_number << setw(10);
cout << workers[i].personal.adress.city << setw(12) << workers[i].personal.adress.street << setw(8) << workers[i].personal.adress.house_number << setw(6) << workers[i].personal.adress.flat_number << setw(10);
cout << workers[i].department_name << setw(10) << workers[i].position << setw(8) << workers[i].experience << setw(8) << workers[i].salary << setw(10) << workers[i].work_status << "\n";
}
}
}
void quit(bool &exit, Worker *workers, int number_workers)
{
char save_choice;
cout << "Save changes? (Y/N): ";
cin >> save_choice;
if (tolower(save_choice) == 'y')
{
string file_name;
cout << "Enter file name to save: ";
cin >> file_name;
writeToFile(file_name, workers, number_workers);
}
char exit_choice;
cout << "Are you sure you want to exit? (Y/N): ";
cin >> exit_choice;
if (tolower(exit_choice) == 'y')
{
cout << "Bye!\n";
exit = true;
}
}
void deleteRecord(Worker *&workers, int &number_workers, int pos_record, Department *&departments, int number_departments)
{
if (workers == NULL)
cout << "Database is empty\n";
else
{
--pos_record;
if (pos_record < 0 || pos_record >= number_workers)
cout << "Database doesn't have any record with this number\n";
else
{
Worker *new_workers = new Worker[number_workers - 1];
for (int i = 0; i < pos_record; ++i)
new_workers[i] = workers[i];
for (int i = pos_record; i < number_workers - 1; ++i)
new_workers[i] = workers[i + 1];
deleteWorkerFromTheDepartment(departments, number_departments, workers[pos_record]);
delete[]workers;
workers = new_workers;
--number_workers;
cout << "\n\tWORKER DELETED SUCCESSFULLY\n";
}
}
}
void printOnlyPhoneNumber(const Worker worker)
{
cout << "\tID" << setw(10) << "Name" << setw(15) << setw(15) << "Surname" << setw(15) << "Phone number\n";
cout << "--------------------------------------------------------------------------------------------\n";
cout << "\t" << worker.ID << setw(10) << worker.personal.name << setw(15) << worker.personal.surname << setw(15) << worker.personal.phone_number << "\n";
}
void searchRecordBySurname(const Worker *workers, int number_workers, string search_key, char mod = 'a')
{
if (workers == NULL)
cout << "Database is empty\n";
bool search = false;
for (int i = 0; i < number_workers; ++i)
{
if (workers[i].personal.surname == search_key)
{
if (mod == 'a')
printRecord(workers[i]);
else
printOnlyPhoneNumber(workers[i]);
search = true;
}
}
if (!search)
cout << "Not found " << search_key << "!\n";
}
void sortRecordByDepartmnets(Department *departments, int number_departments)
{
if (departments != NULL)
{
int pos_min;
string min;
Department temp_department;
for (int i = 0; i < number_departments - 1; i++)
{
pos_min = i;
min = departments[i].dep_name;
for (int j = 1 + i; j < number_departments; j++)
{
if (departments[j].dep_name < min)
{
min = departments[j].dep_name;
pos_min = j;
}
}
temp_department = departments[pos_min];
departments[pos_min] = departments[i];
departments[i] = temp_department;
}
for (int i = 0; i < number_departments; ++i)
{
if (departments[i].number_workers != 0)
{
headPrintRecord();
for (int j = 0; j < departments[i].number_workers; ++j)
printRecord(departments[i].workers[j]);
cout << "\n";
}
}
}
else
cout << "Database is empty\n";
}
void sortRecordByPosition(Worker *workers, int number_workers)
{
if (workers != NULL)
{
int pos_min;
string min;
Worker temp_worker;
for (int i = 0; i < number_workers - 1; i++)
{
pos_min = i;
min = workers[i].position;
for (int j = 1 + i; j < number_workers; j++)
{
if (workers[j].position < min)
{
min = workers[j].position;
pos_min = j;
}
}
temp_worker = workers[pos_min];
workers[pos_min] = workers[i];
workers[i] = temp_worker;
}
showAllWorkers(workers, number_workers);
}
else
cout << "Database is empty\n";
}
void selectByDepartments(string select_name_department, Department *departments, int number_departments)
{
if (departments != NULL)
{
int i = 0;
while (i < number_departments && departments[i].dep_name != select_name_department)
++i;
if (i < number_departments)
showAllWorkers(departments[i].workers, departments[i].number_workers);
else
cout << "This department does not exist\n";
}
}
void calculateNumberWorkers(const Department *departments, int number_departments)
{
if (departments == NULL)
cout << "Database is empty\n";
else
{
cout << "\nDepartment name " << setw(20) << "Number of workers\n";
cout << "-------------------------------------------------\n";
for (int i = 0; i < number_departments; ++i)
cout << departments[i].dep_name << setw(20) << departments[i].number_workers << "\n";
}
}
void calculateTotalFundsbyDepartment(Department *&departments, int number_departments)
{
if (departments == NULL)
cout << "Database is empty\n";
else
{
for (int i = 0; i < number_departments; ++i)
{
departments[i].funds = 0;
for (int j = 0; j < departments[i].number_workers; ++j)
departments[i].funds += departments[i].workers[j].salary;
}
cout << "\nDepartment name " << setw(25) << "Total funds by department\n";
cout << "-------------------------------------------------\n";
for (int i = 0; i < number_departments; ++i)
cout << departments[i].dep_name << setw(30) << departments[i].funds << "\n";
}
}
void deleteInfoByFiredWorker(Worker *&workers, int &number_workers, Department *&departments, int number_departments)
{
if (workers == NULL)
cout << "Database is empty\n";
else
{
char user_delete_answer;
cout << "Do you want delete all fired workers? (Y/N): ";
cin >> user_delete_answer;
if (tolower(user_delete_answer) == 'y')
{
for (int i = 0; i < number_workers; ++i)
if (workers[i].work_status == "fired")
deleteRecord(workers, number_workers, i + 1, departments, number_departments);
}
else
{
int delete_worker_ID;
cout << "Enter ID worker that you want to delete: ";
cin >> delete_worker_ID;
int i = 0;
while (i < number_workers && workers[i].ID != delete_worker_ID)
++i;
if (i < number_workers)
{
if (workers[i].work_status == "fired")
deleteRecord(workers, number_workers, i + 1, departments, number_departments);
else
{
cout << "A worker with this ID not fired\n";
cout << "Are you sure that you want to remove information about him?(Y/N): ";
cin >> user_delete_answer;
if (tolower(user_delete_answer) == 'y')
deleteRecord(workers, number_workers, i + 1, departments, number_departments);
}
}
else
cout << "A worker with this ID does not exist!\n";
}
}
}
void staffMove(Worker &worker, Department *&departments, int &number_departments)
{
if (departments == NULL)
cout << "Database is empty\n";
else
{
string name_department;
cout << "Enter the name of the department which should to transfer a worker: ";
cin >> name_department;
deleteWorkerFromTheDepartment(departments, number_departments, worker);
worker.department_name = name_department;
addWorkerInDepartment(departments, number_departments, worker);
cout << "WORKER MOVED SUCCESSFULLY\n";
}
}
void listWorkerByDepartment(Department *departments, int number_department)
{
if (departments == NULL)
cout << "Database is empty\n";
else
{
for (int i = 0; i < number_department; ++i)
{
cout << "\n\t----------------" << departments[i].dep_name << "------------------\n\n";
headPrintRecord();
for (int j = 0; j < departments[i].number_workers; ++j)
printRecord(departments[i].workers[j]);
cout << "\n";
}
}
}
void totalFunds(Department *departments, int number_department)
{
if (departments == NULL)
cout << "Database is empty\n";
else
{
calculateTotalFundsbyDepartment(departments, number_department);
int total_funds = 0;
for (int i = 0; i < number_department; ++i)
total_funds += departments[i].funds;
cout << "--------------------------------------------------------\n";
cout << "\n\tTOTAL FUNDS: " << total_funds << "\n";
}
}
enum menuitems {CREATE_DATABASE, LOAD_FROM_FILE, SHOW_ALL, ADD_WORKER,
DELETE_WORKER, SEARCH_BY_SURNAME, SORT_BY_DEPARTMENT, SORT_BY_POSITION,
SELECT_BY_DEPARTMENT,CALCULATE_NUMBER_OF_WORKERS, CALCULATE_TOTAL_FUNDS_DEPARTMENT, DELETE_INFO_BY_FIRED_WORKER,
STAFF_MOVE, LIST_WORKER_BY_DEPARTMENT, TOTAL_FUNDS, EXIT};
const int NUMBER_MENU = 17;
ITEM menu[NUMBER_MENU] = {
{30, 13, "CREATE DATABASE" },
{30, 15, "LOAD DATABASE FROM FILE" },
{30, 17, "SHOW ALL WORKERS" },
{30, 19, "ADD WORKER" },
{30, 21, "DELETE WORKER"},
{30, 23, "SEARCH WORKER BY SURNAME"},
{30, 25, "SORT BY DEPARTMENTS"},
{30, 27, "SORT BY POSITION" },
{30, 29, "SELECT BY DEPARTMENT" },
{30, 31, "CALCULATE: NUMBER OF WORKERS IN DEPARTEMENT"},
{30, 33, "CALCULATE: TOTAL FUNDS BY DEPARTMENT"},
{30, 35, "EDIT: DELETE INFO BY FIRED WORKER"},
{30, 37, "EDIT: STAFF MOVE"},
{30, 39, "REPORT: LIST WORKERS BY DEPARTMENT"},
{30, 41, "REPORT: TOTAL FUNDS"},
{30, 43, "EXIT" } };
void itemMenu(int sel, bool activate)
{
WORD itemAttributes;
if (activate)
itemAttributes = activeItemAttributes;
else
itemAttributes = inactiveItemAttributes;
gotoxy(menu[sel].x, menu[sel].y);
SetConsoleTextAttribute(hStdOut, itemAttributes);
cout << menu[sel].name_menu;
}
bool menuAction(int sel, Worker *&workers, int &number_workers, Department *&departments, int &number_departments)
{
showCursor(true);
int user_choice;
bool exit = false;
string load_file_name;
string search_surname;
string select_departments_name;
switch (sel)
{
case CREATE_DATABASE:
system("cls");
if (workers == NULL)
cout << "\tYou create a new database!\n";
else
{
char user_answer_choice;
cout << "When you create a new database possible loss of data. Save an existing base? (Y/N): \n";
cin >> user_answer_choice;
if (tolower(user_answer_choice) == 'y')
{
string save_file_name;
cout << "Enter file name to save: ";
cin >> save_file_name;
writeToFile(save_file_name, workers, number_workers);
}
}
workers = createNewBaseWorker(number_workers, departments, number_departments);
cout << "Database created successfully\n";
break;
case SHOW_ALL:
system("cls");
cout << "\n\nNUMBER WORKERS: " << number_workers << "\n\n";
showAllWorkers(workers, number_workers);
break;
case ADD_WORKER:
system("cls");
addRecord(workers, number_workers, departments, number_departments);
cout << "\n\tWORKER ADDED SUCCESSFULLY\n";
break;
case DELETE_WORKER:
system("cls");
int pos_delete_worker;
if (workers != NULL)
{
cout << "Enter the number of worker to delete of base: ";
cin >> pos_delete_worker;
}
deleteRecord(workers, number_workers, pos_delete_worker, departments, number_departments);
break;
case SEARCH_BY_SURNAME:
system("cls");
cout << "Enter a surname of worker to find of base: ";
cin >> search_surname;
char user_search_answer;
cout << "Print all info of worker (a) or only phone number (p)?: ";
cin >> user_search_answer;
searchRecordBySurname(workers, number_workers, search_surname, user_search_answer);
break;
case SORT_BY_DEPARTMENT:
system("cls");
sortRecordByDepartmnets(departments, number_departments);
break;
case SORT_BY_POSITION:
system("cls");
sortRecordByPosition(workers, number_workers);
break;
case SELECT_BY_DEPARTMENT:
system("cls");
cout << "Enter a departments name to select: ";
cin >> select_departments_name;
selectByDepartments(select_departments_name, departments, number_departments);
break;
case LOAD_FROM_FILE:
system("cls");
if (workers != NULL)
{
char user_choice;
cout << "You will lose your data! Continue?(Y/N)";
cin >> user_choice;
if (tolower(user_choice) == 'y')
{
char user_answer_choice;
cout << "Save an existing base ? (Y / N): ";
cin >> user_answer_choice;
if (tolower(user_answer_choice) == 'y')
{
string save_file_name;
cout << "Enter file name to save: ";
cin >> save_file_name;
writeToFile(save_file_name, workers, number_workers);
}
delete[]workers;
workers = NULL;
if (departments != NULL)
{
delete[]departments;
departments = NULL;
}
}
}
else
cout << " You will create a new database from the file\n";
cout << "Enter file name to load: ";
cin >> load_file_name;
loadFromFile(load_file_name, workers, number_workers, departments, number_departments);
break;
case CALCULATE_NUMBER_OF_WORKERS:
system("cls");
calculateNumberWorkers(departments, number_departments);
break;
case CALCULATE_TOTAL_FUNDS_DEPARTMENT:
system("cls");
calculateTotalFundsbyDepartment(departments, number_departments);
break;
case DELETE_INFO_BY_FIRED_WORKER:
system("cls");
deleteInfoByFiredWorker(workers, number_workers, departments, number_departments);
break;
case STAFF_MOVE:
system("cls");
int move_worker_number;
cout << "Enter the number of worker to move him in the another department: ";
cin >> move_worker_number;
staffMove(workers[move_worker_number - 1], departments, number_departments);
break;
case LIST_WORKER_BY_DEPARTMENT:
system("cls");
listWorkerByDepartment(departments, number_departments);
break;
case TOTAL_FUNDS:
system("cls");
totalFunds(departments, number_departments);
break;
case EXIT:
system("cls");
quit(exit, workers, number_workers);
break;
}
return exit;
}
void DrawMenu(Worker *workers, int number_workers, Department *departments, int number_departments)
{
menuitems sel = CREATE_DATABASE; // Number of the current menu item
SetConsoleTextAttribute(hStdOut, inactiveItemAttributes);
system("cls");
for (int i = 0; i < NUMBER_MENU; i++)
{
gotoxy(menu[i].x, menu[i].y);
cout << menu[i].name_menu;
}
itemMenu(sel, true);
showCursor(false);
fflush(stdin);
int iKey;
bool exit = false;
while (!exit)
{
if (_kbhit())
{
iKey = _getch();
switch (iKey)
{
case DOWN:
if (sel < NUMBER_MENU - 1) {
itemMenu(sel, false);
sel = (menuitems)(sel + 1);
itemMenu(sel, true);
}
else {
itemMenu(sel, false);
sel = CREATE_DATABASE;
itemMenu(sel, true);
}
showCursor(false);
break;
case UP:
if (sel >0) {
itemMenu(sel, false);
sel = (menuitems)(sel - 1);
itemMenu(sel, true);
}
else {
itemMenu(sel, false);
sel = EXIT;
itemMenu(sel, true);
}
showCursor(false);
break;
case ENTER:
gotoxy(curspos.X, curspos.Y);// Moves the cursor from the menu bar at the same position
SetConsoleTextAttribute(hStdOut, workWindowAttributes);
exit = menuAction(sel, workers, number_workers, departments, number_departments);
_getch();
if (!exit) DrawMenu(workers, number_workers, departments, number_departments);
break;
case ESCAPE:
system("cls");
quit(exit, workers, number_workers);
getCursorPosition(); //program completion
} // switch
} // if (kbhit)
} // while (!exit)
}
int main()
{
int number_workers = 0, number_departments = 0;
Worker *staff = NULL;
Department *departments = NULL;
SetConsoleTitle(L"MENU");
GetConsoleScreenBufferInfo(hStdOut, &csbInfo);
consolRect = csbInfo.srWindow; // coordinates of the corners console
SetConsoleTextAttribute(hStdOut, workWindowAttributes);
system("cls"); //set attributes of color workspace
if (SetWindow(135, 50))
DrawMenu(staff, number_workers, departments, number_departments);
for (int i = 0; i < number_departments; ++i)
delete[]departments[i].workers;
delete[]departments;
delete[]staff;
return 0;
}
Здавалося, й тут нічого страшного, але... Ось дійшла до такого:
▼Прихований текст
void WriteToFile(ofstream &out)
{
out.write(reinterpret_cast<char*>(&account_number_salary), sizeof(account_number_salary));
out.write(reinterpret_cast<char*>(surname.c_str), surname.length());
out.write(reinterpret_cast<char*>(name.c_str), name.length());
out.write(reinterpret_cast<char*>(birthday.c_str), birthday.length());
out.write(reinterpret_cast<char*>(city.c_str), city.length());
out.write(reinterpret_cast<char*>(street.c_str), street.length());
out.write(reinterpret_cast<char*>(&house_number), sizeof(house_number));
out.write(reinterpret_cast<char*>(&flat_number), sizeof(flat_number));
out.write(reinterpret_cast<char*>(phone_number.c_str), phone_number.length());
out.write(reinterpret_cast<char*>(education.c_str), education.length());
out.write(reinterpret_cast<char*>(&experience), sizeof(experience));
out.write(reinterpret_cast<char*>(&total_projects_cost), sizeof(total_projects_cost));
out.write(reinterpret_cast<char*>(position.GetName().c_str), position.GetName().length());
out.write(reinterpret_cast<char*>(position.GetWorkingHours()), sizeof(position.GetWorkingHours()));
out.write(reinterpret_cast<char*>(position.GetSalary()),sizeof(position.GetSalary()));
out.write(reinterpret_cast<char*>(position.GetNumberWorkDuties()), sizeof(position.GetNumberWorkDuties()));
for (int i = 0; i < position.GetNumberWorkDuties(); ++i)
out.write(reinterpret_cast<char*>(position.GetWorkDutieByPosition(i + 1).c_str), position.GetWorkDutieByPosition(i + 1).length());
out.write(reinterpret_cast<char*>(¤t_number_projects), sizeof(current_number_projects));
for (int i = 0; i < current_number_projects; ++i)
{
out.write(reinterpret_cast<char*>(projects[i].GetName().c_str), projects[i].GetName().length());
out.write(reinterpret_cast<char*>(projects[i].GetDuration()), sizeof(projects[i].GetDuration()));
out.write(reinterpret_cast<char*>(projects[i].GetWorkingHours()), sizeof(projects[i].GetWorkingHours()));
out.write(reinterpret_cast<char*>(projects[i].GetProjectCost()), sizeof(projects[i].GetProjectCost()));
out.write(reinterpret_cast<char*>(projects[i].GetNameCustomer().c_str), projects[i].GetNameCustomer().length());
}
out.write(reinterpret_cast<char*>(department.GetName().c_str),department.GetName().length());
out.write(reinterpret_cast<char*>(department.GetMajorDepartmentName().c_str), department.GetMajorDepartmentName().length());
out.write(reinterpret_cast<char*>(department.GetAmountPrize()), sizeof(department.GetAmountPrize()));
//out.write(reinterpret_cast<char*>(department.GetNumberWorkers()), sizeof(department.GetNumberWorkers()));
//for (int i = 0; i < department.GetNumberWorkers(); ++i)
// out.write(reinterpret_cast<char*>);
out.write(reinterpret_cast<char*>(department.GetNumberPositions()), sizeof(department.GetNumberPositions()));
for (int i = 0; i < department.GetNumberPositions(); ++i)
out.write(reinterpret_cast<char*>(department.GetPosition(i + 1).c_str), department.GetPosition(i + 1).length());
}
Проблеми, які виникли і не знаю з якого боку тепер підступитися:
1. Не можу серіалізувати поля типу double. Як з ними правильно поступити?
2. При записі у файл підрозділу, в кому є Worker, потрібно записати масив об'єктів Worker, які працюють у цьому підрозділі. А це виходить замкнене коло. Як????