fix some file I/O bugs, refactor HashTable writeToFile as friend function

This commit is contained in:
Iurii Tatishchev 2024-06-19 22:25:48 -07:00
parent a2746fe6de
commit ee9b2e6302
Signed by: CaZzzer
GPG Key ID: E0EBF441EA424369
6 changed files with 93 additions and 86 deletions

44
CPU.cpp
View File

@ -2,7 +2,7 @@
#include "CPU.h" #include "CPU.h"
#include "utils.h" #include "utils.h"
using std::string, std::ostream, std::endl, std::cout; using namespace std;
void display(const CPU &cpu) { void display(const CPU &cpu) {
@ -15,38 +15,38 @@ void display(const CPU &cpu) {
// Release Year // Release Year
cout << "| "; cout << "| ";
cout.width(widths[0] + 7); cout.width(widths[0] + 7);
cout << std::left << boldStr("Release Year"); cout << left << boldStr("Release Year");
cout << "|"; cout << "|";
cout.width(widths[1] - 1); cout.width(widths[1] - 1);
cout << std::right << cpu.releaseYear; cout << right << cpu.releaseYear;
cout << " |\n"; cout << " |\n";
// Core Count // Core Count
cout << "| "; cout << "| ";
cout.width(widths[0] + 7); cout.width(widths[0] + 7);
cout << std::left << boldStr("Core Count"); cout << left << boldStr("Core Count");
cout << "|"; cout << "|";
cout.width(widths[1] - 1); cout.width(widths[1] - 1);
cout << std::right << cpu.coreCount; cout << right << cpu.coreCount;
cout << " |\n"; cout << " |\n";
// Architecture // Architecture
cout << "| "; cout << "| ";
cout.width(widths[0] + 7); cout.width(widths[0] + 7);
cout << std::left << boldStr("Architecture"); cout << left << boldStr("Architecture");
cout << "|"; cout << "|";
cout.width(widths[1] - 1); cout.width(widths[1] - 1);
cout << std::right << cpu.architecture; cout << right << cpu.architecture;
cout << " |\n"; cout << " |\n";
// Base Clock // Base Clock
cout << "| "; cout << "| ";
cout.width(widths[0] + 7); cout.width(widths[0] + 7);
cout << std::left << boldStr("Base Clock (GHz)"); cout << left << boldStr("Base Clock (GHz)");
cout << "|"; cout << "|";
cout.width(widths[1] - 1); cout.width(widths[1] - 1);
cout.precision(2); cout.precision(2);
cout << std::fixed << std::right << cpu.baseClock; cout << fixed << right << cpu.baseClock;
cout << " |\n"; cout << " |\n";
printTableFooter(widths); printTableFooter(widths);
@ -55,50 +55,50 @@ void display(const CPU &cpu) {
void iDisplay(const CPU &cpu, int level) { void iDisplay(const CPU &cpu, int level) {
for (int i = 0; i < level; i++) for (int i = 0; i < level; i++)
cout << " "; cout << " ";
cout << cpu.cpuId << std::endl; cout << cpu.cpuId << endl;
} }
void rowDisplay(const CPU &cpu, const std::vector<int> &widths) { void rowDisplay(const CPU &cpu, const vector<int> &widths) {
cout << "| "; cout << "| ";
cout.width(widths[0] - 1); cout.width(widths[0] - 1);
cout << std::left << cpu.cpuId; cout << left << cpu.cpuId;
cout << "|"; cout << "|";
cout.width(widths[1] - 1); cout.width(widths[1] - 1);
cout << std::right << cpu.releaseYear; cout << right << cpu.releaseYear;
cout << " |"; cout << " |";
cout.width(widths[2] - 1); cout.width(widths[2] - 1);
cout << std::right << cpu.coreCount; cout << right << cpu.coreCount;
cout << " | "; cout << " | ";
cout.width(widths[3] - 1); cout.width(widths[3] - 1);
cout << std::left << cpu.architecture; cout << left << cpu.architecture;
cout << "|"; cout << "|";
cout.width(widths[4] - 1); cout.width(widths[4] - 1);
cout.precision(2); cout.precision(2);
cout << std::fixed << std::right << cpu.baseClock; cout << fixed << right << cpu.baseClock;
cout << " |\n"; cout << " |\n";
} }
ostream &operator<<(ostream &os, const CPU &cpu) { ostream &operator<<(ostream &os, const CPU &cpu) {
os << "CPU ID: " << cpu.cpuId << std::endl; os << "CPU ID: " << cpu.cpuId << endl;
return os; return os;
} }
int key_to_index(const CPU &key, int size) { int key_to_index(const CPU &key, int size) {
std::string k = key.getCpuId(); string k = key.getCpuId();
int sum = 0; int sum = 0;
for (int i = 0; k[i]; i++) for (int i = 0; k[i]; i++)
sum += k[i]; sum += k[i];
return sum % size; return sum % size;
} }
std::string to_string(const CPU &cpu) { string to_string(const CPU &cpu) {
return cpu.cpuId + "; " + return cpu.cpuId + "; " +
std::to_string(cpu.releaseYear) + "; " + to_string(cpu.releaseYear) + "; " +
std::to_string(cpu.coreCount) + "; " + to_string(cpu.coreCount) + "; " +
cpu.architecture + "; " + cpu.architecture + "; " +
std::to_string(cpu.baseClock) + ";"; to_string(cpu.baseClock) + ";";
} }

View File

@ -2,11 +2,20 @@
#define INC_08_TEAM_PROJECT_HASHTABLE_H #define INC_08_TEAM_PROJECT_HASHTABLE_H
#include <fstream> #include <fstream>
#include <iostream>
#include <functional>
#include "HashNode.h" #include "HashNode.h"
#include "CPU.h" #include "CPU.h"
#include "utils.h" #include "utils.h"
using std::string, std::ofstream, std::cout, std::endl; using namespace std;
// Forward declaration for friend function
template<typename T>
class HashTable;
template<typename T>
void writeToFile(const HashTable<T> &hashTable, const string &filename, string visit(const T &));
template<typename T> template<typename T>
class HashTable { class HashTable {
@ -18,7 +27,7 @@ private:
public: public:
HashTable() { HashTable() {
count = 0; count = 0;
hashSize = 97; hashSize = 3;
hashAry = new HashNode<T>[hashSize]; hashAry = new HashNode<T>[hashSize];
} }
@ -50,9 +59,9 @@ public:
int search(T &itemOut, const T &key, int h(const T &key, int size)) const; int search(T &itemOut, const T &key, int h(const T &key, int size)) const;
void outputFile(const string &filename, string visit(const T &));
void reHash(int h(const T &key, int size)); void reHash(int h(const T &key, int size));
friend void writeToFile<T>(const HashTable<T> &hashTable, const string &filename, string visit(const T &));
}; };
/*~*~*~* /*~*~*~*
@ -162,58 +171,31 @@ int HashTable<T>::search(T &itemOut, const T &key, int h(const T &key, int size)
} }
template<class T> template<class T>
void HashTable<T>::outputFile(const string &filename, string visit(const T &)) { void HashTable<T>::reHash(int h(const T &key, int size)) {
ofstream outputFile(filename);
cout << "Outputting data to \"" << filename << "\"" << endl;
if (!outputFile.good()) {
cout << "Error opening the output file: \"" << filename << "\"" << endl;
exit(EXIT_FAILURE);
}
T aT;
if (hashAry[0].getOccupied() == 1) {
aT = hashAry[0].getItem();
outputFile << visit(aT);
}
for (int i = 1; i < hashSize; i++) {
if (hashAry[i].getOccupied() == 1) {
aT = hashAry[i].getItem();
outputFile << endl << visit(aT);
}
}
outputFile.close();
}
template<class T>
void HashTable<T>::reHash(int h(const T &key, int size)){
int nHashSize = hashSize * 2; int nHashSize = hashSize * 2;
nHashSize = findNextPrime(nHashSize); nHashSize = findNextPrime(nHashSize);
HashNode<T>* nHashAry = new HashNode<T>[nHashSize]; HashNode<T> *nHashAry = new HashNode<T>[nHashSize];
// Goes through each bucket and puts it in the new array // Goes through each bucket and puts it in the new array
T aT; T aT;
for(int i = 0; i < hashSize; i++){ for (int i = 0; i < hashSize; i++) {
if(hashAry[i].getOccupied() == 1){ if (hashAry[i].getOccupied() == 1) {
aT = hashAry[i].getItem(); aT = hashAry[i].getItem();
int nIndex = h(aT, nHashSize); int nIndex = h(aT, nHashSize);
for(int j = 0; j < hashSize; j++){ for (int j = 0; j < hashSize; j++) {
if(nHashAry[nIndex].getOccupied() != 1){ if (nHashAry[nIndex].getOccupied() != 1) {
nHashAry[nIndex].setItem(aT); nHashAry[nIndex].setItem(aT);
nHashAry[nIndex].setOccupied(1); nHashAry[nIndex].setOccupied(1);
nHashAry[nIndex].setNumCollisions(i); nHashAry[nIndex].setNumCollisions(i);
break; break;
} }
nIndex = (nIndex + 1) % hashSize; nIndex = (nIndex + 1) % hashSize;
} }
} }
} }
@ -222,4 +204,27 @@ void HashTable<T>::reHash(int h(const T &key, int size)){
hashSize = nHashSize; hashSize = nHashSize;
} }
template<typename T>
void writeToFile(const HashTable<T> &hashTable, const string &filename, string visit(const T &)) {
ofstream outputFile(filename);
if (!outputFile.good()) {
cout << "Error opening the output file: \"" << filename << "\"" << endl;
exit(EXIT_FAILURE);
}
outputFile.flush();
T aT;
for (int i = 0; i < hashTable.hashSize; i++) {
if (hashTable.hashAry[i].getOccupied() == 1) {
aT = hashTable.hashAry[i].getItem();
outputFile << visit(aT) << '\n';
}
}
outputFile.close();
}
#endif // INC_08_TEAM_PROJECT_HASHTABLE_H #endif // INC_08_TEAM_PROJECT_HASHTABLE_H

13
fio.cpp
View File

@ -5,7 +5,7 @@ bool isInteger(const string &str);
bool isDouble(const string &str); bool isDouble(const string &str);
using std::stringstream, std::ifstream, std::getline, std::cout, std::endl, std::stoi, std::stod, std::cin; using namespace std;
int findHashSize(const string &filename) { int findHashSize(const string &filename) {
ifstream inputFile(filename); ifstream inputFile(filename);
@ -14,7 +14,7 @@ int findHashSize(const string &filename) {
cout << "Error opening the input file: \"" << filename << "\"" << endl; cout << "Error opening the input file: \"" << filename << "\"" << endl;
return -1; return -1;
} }
cout << "Reading data from \"" << filename << "\"" << endl; // cout << "Reading data from \"" << filename << "\"" << endl;
int count = 0; int count = 0;
string line; string line;
@ -30,7 +30,7 @@ int findHashSize(const string &filename) {
void insertFile(const string &filename, BinarySearchTree<string> &bst, HashTable<CPU> &hash) { void insertFile(const string &filename, BinarySearchTree<string> &bst, HashTable<CPU> &hash) {
ifstream inputFile(filename); ifstream inputFile(filename);
cout << "Reading data from \"" << filename << "\"" << endl; // cout << "Reading data from \"" << filename << "\"" << endl;
if (!inputFile) { if (!inputFile) {
cout << "Error opening the input file: \"" << filename << "\"" << endl; cout << "Error opening the input file: \"" << filename << "\"" << endl;
@ -80,7 +80,8 @@ void insertCPU(BinarySearchTree<string> &bst, HashTable<CPU> &hash) {
double baseClock; double baseClock;
cout << "Please enter the name of the CPU: "; cout << "Please enter the name of the CPU: ";
cin >> name; cin.ignore();
getline(cin, name);
CPU key(name, -1, -1, "", -1); CPU key(name, -1, -1, "", -1);
CPU checker; CPU checker;
@ -115,8 +116,8 @@ void insertCPU(BinarySearchTree<string> &bst, HashTable<CPU> &hash) {
// Strings don't need to be tested // Strings don't need to be tested
cout << "Please enter the architecture of the CPU: "; cout << "Please enter the architecture of the CPU: ";
cin >> architecture; cin.ignore();
getline(cin, architecture);
cout << "Please enter the base clock of the CPU: "; cout << "Please enter the base clock of the CPU: ";
cin >> tester; cin >> tester;

View File

@ -26,7 +26,6 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <vector>
#include "utils.h" #include "utils.h"
#include "CPU.h" #include "CPU.h"
#include "HashTable.h" #include "HashTable.h"
@ -37,7 +36,9 @@
#include "DisplayManager.h" #include "DisplayManager.h"
#include "SearchManager.h" #include "SearchManager.h"
using std::cin, std::cout, std::string, std::vector; using namespace std;
const string DEFAULT_FILE = "out.txt";
void processInput(char command, HashTable<CPU> &table, BinarySearchTree<string> &tree, void processInput(char command, HashTable<CPU> &table, BinarySearchTree<string> &tree,
UndoManager<CPU> &undoManager, DisplayManager<CPU> &displayManager, UndoManager<CPU> &undoManager, DisplayManager<CPU> &displayManager,
@ -47,9 +48,12 @@ int main() {
// Print help table for commands // Print help table for commands
printHelp(); printHelp();
HashTable<CPU> cpuTable; int hashSize = findHashSize(DEFAULT_FILE);
HashTable<CPU> cpuTable = HashTable<CPU>(hashSize);
BinarySearchTree<string> cpuTree; BinarySearchTree<string> cpuTree;
// Stack<CPU> undoStack;
// Read initial data from output file
insertFile(DEFAULT_FILE, cpuTree, cpuTable);
DisplayManager<CPU> displayManager(&cpuTable, &cpuTree); DisplayManager<CPU> displayManager(&cpuTable, &cpuTree);
SearchManager<CPU> searchManager(&cpuTable); SearchManager<CPU> searchManager(&cpuTable);
@ -69,7 +73,7 @@ int main() {
} }
} }
// Quit command received // Quit command received
cpuTable.outputFile("output.txt", to_string); writeToFile(cpuTable, DEFAULT_FILE, to_string);
cout << "Exiting program...\n"; cout << "Exiting program...\n";
return 0; return 0;
@ -142,9 +146,6 @@ void handleFileInput(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree)
string filename; string filename;
cout << "Enter filename: "; cout << "Enter filename: ";
cin >> filename; cin >> filename;
int hashSize = findHashSize(filename);
hashTable = HashTable<CPU>(hashSize);
tree.clear();
insertFile(filename, tree, hashTable); insertFile(filename, tree, hashTable);
cout << "Data from file \"" << filename << "\" added.\n"; cout << "Data from file \"" << filename << "\" added.\n";
@ -172,7 +173,7 @@ void handleFileOutput(HashTable<CPU> &hashTable, UndoManager<CPU> &undoManager)
string filename; string filename;
cout << "Enter filename: "; cout << "Enter filename: ";
cin >> filename; cin >> filename;
hashTable.outputFile(filename, to_string); writeToFile(hashTable, filename, to_string);
undoManager.clearUndoStack(); undoManager.clearUndoStack();
cout << "Data written to file \"" << filename << "\".\n"; cout << "Data written to file \"" << filename << "\".\n";
} }

View File

@ -1,14 +1,14 @@
#include <iostream> #include <iostream>
#include "utils.h" #include "utils.h"
using std::cout; using namespace std;
void printRow(const vector<int> &widths, const vector<string> &row) { void printRow(const vector<int> &widths, const vector<string> &row) {
cout << '|'; cout << '|';
for (int i = 0; i < widths.size(); i++) { for (int i = 0; i < widths.size(); i++) {
cout << ' '; cout << ' ';
cout.width(widths[i] - 1); cout.width(widths[i] - 1);
cout << std::left << row[i]; cout << left << row[i];
cout << '|'; cout << '|';
} }
cout << '\n'; cout << '\n';
@ -30,7 +30,7 @@ void printTableHeader(const vector<int> &widths, const vector<string> &headers)
for (int i = 0; i < widths.size(); i++) { for (int i = 0; i < widths.size(); i++) {
cout << ' '; cout << ' ';
cout.width(widths[i] - 1); cout.width(widths[i] - 1);
cout << std::left << headers[i]; cout << left << headers[i];
cout << '|'; cout << '|';
} }
cout << '\n'; cout << '\n';
@ -90,8 +90,8 @@ void printHelp() {
{"W", "Write data to a file"}, {"W", "Write data to a file"},
{"T", "Hashtable statistics"}, {"T", "Hashtable statistics"},
{"Q", "Quit"}, {"Q", "Quit"},
{"P", "Hidden print option (do not show it in the menu: print indented tree)"}, // {"P", "Hidden print option (do not show it in the menu: print indented tree)"},
{"Z", "Hidden option (do not show it in the menu: display names of team members)"}, // {"Z", "Hidden option (do not show it in the menu: display names of team members)"},
}; };
printTable(helpWidths, helpData); printTable(helpWidths, helpData);
} }

View File

@ -4,7 +4,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
using std::vector, std::string; using namespace std;
void printRow(const vector<int> &widths, const vector<string> &row); void printRow(const vector<int> &widths, const vector<string> &row);