// // Created by caleb on 3/25/24. // #include #include #include #include #include "structures.h" Employee::Employee(char * pName, double salary) { //this->pName = reinterpret_cast(std::malloc(strlen(pName) * sizeof(char))); this->pName = strdup( pName); this->salary = salary; memset(&this->nameOfSpouse, 0, 50); this->pAddress = nullptr; strcpy(this->nameOfSpouse, "Not defined!"); } Employee::Employee(char * pName, char * pAddress, char nameOfSpouse[50], double salary) { this->pName = strdup(pName); this->pAddress = strdup(pAddress); memcpy(&this->nameOfSpouse, &nameOfSpouse, 50); this->salary = salary; } Employee::~Employee() { free(this->pName); free(this->pAddress); } /* These copy constructors are required in order to be able to use the constructors in populate() */ Employee &Employee::operator=(const Employee &rhs) { if (rhs.pName != nullptr) { this->pName = strdup(rhs.pName); } pAddress = strdup(rhs.pAddress); memcpy(&nameOfSpouse, &rhs.nameOfSpouse, 50); salary = rhs.salary; return *this; } Employee::Employee(const Employee &rhs) { *this = rhs; }; Employee &Employee::operator=(Employee &&rhs) { free(this->pName); pName = rhs.pName; rhs.pName = nullptr; free(pAddress); pAddress = rhs.pAddress; rhs.pAddress = nullptr; memcpy(&nameOfSpouse, &rhs.nameOfSpouse, 50); salary = rhs.salary; return *this; } Employee::Employee(Employee &&rhs) { *this = std::move(rhs); } std::string Employee::toString() { std::string outputString; outputString.append("pName: ").append(this->pName).append("\n"); if (this->pAddress != nullptr) { outputString.append("pAddress: ").append(this->pAddress).append("\n"); } if (this->nameOfSpouse != nullptr) { outputString.append("nameOfSpouse: ").append(this->nameOfSpouse).append("\n"); } outputString.append("salary: ").append(std::to_string(this->salary)).append("\n"); return outputString; } bool isValid(std::string name, std::string salaryInput) { bool isValid = false; if ((std::atof(salaryInput.c_str()) > 0.0) && name.length() > 0) { isValid = true; } if (!isValid) { printf("Invalid input! Please try again!\n"); } return isValid; } /** Populates a dynamic 2D array of employees by reading the data from the console. * Note: this is awful and incredibly fragile. the slightest misalignment causes it to corrupt memory and leads to undefined behavior. Using an std::vector would be infinately better, but alas... * @param pp existing 2D array to be populated. * @param rows number of rows * @param col number of columns */ void populate(Employee **pp, int rows, int col ) { std::string name, salaryInput; double salary; printf("Populating a %i x %i 2D array... (Total entries required: %i)\n", rows, col, (rows * col)); for (int i = 0; i < rows; ++i) { for (int j = 0; j < col; ++j) { do { printf("Enter a name for the employee at (%i x %i): ", i, j); std::getline(std::cin, name); printf("Enter salary for %s: ", name.c_str()); std::getline(std::cin, salaryInput); } while (!isValid(name, salaryInput)); salary = std::atof(salaryInput.c_str()); char* empName = strdup(name.c_str()); pp[i][j] = Employee(empName, salary); free(empName); } } } /** Prints the 2D dynamic array. * * @param pp the dynamic array * @param rows number of rows * @param col number of columns */ void print(Employee **pp, int rows, int col ) { const std::string DASHES = "-----------"; int employeeNumber = 0; for (int i = 0; i < rows; ++i) { printf("%s Row %i %s\n", DASHES.c_str(), (i + 1), DASHES.c_str()); for(int j = 0; j < col; ++j) { printf("%s Employee %i %s\n", DASHES.c_str(), ++employeeNumber, DASHES.c_str()); printf("%s", pp[i][j].toString().c_str()); } } } /** Frees all memory occupied by the array. * * @param pp the dynamic array * @param rows number of rows * @param col number of columns */ void free(Employee **pp, int rows, int col) { // Iterate over each row for (int i = 0; i < rows; ++i) { //delete the array of Employee pointers delete[] pp[i]; } // Delete the array of row pointers delete[] pp; } bool sortByName (const Employee &lhs, const Employee &rhs) { return strcmp(lhs.pName, rhs.pName) < 0;} /**Sorts the dynamic array in ascending order by name. * * @param pp the dynamic array * @param rows number of rows * @param col number of columns */ void sort(Employee **pp, int rows, int col ) { for(int i = 0; i < rows; i++) { std::sort(&pp[i][0], &pp[i][col], sortByName); } }