ASDV-Cpp/Assignments/lab4-Structures_CalebFontenot/structures.cpp

157 lines
4.8 KiB
C++

//
// Created by caleb on 3/25/24.
//
#include <cstring>
#include <iostream>
#include <limits>
#include <algorithm>
#include "structures.h"
Employee::Employee(char * pName, double salary) {
//this->pName = reinterpret_cast<char*>(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);
}
}