add initial implementation of File I/O
This commit is contained in:
parent
30454d624c
commit
31e276a066
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
@ -1,4 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakePythonSetting">
|
||||
<option name="pythonIntegrationState" value="YES" />
|
||||
</component>
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
@ -18,4 +18,6 @@ add_executable(08_team_project main.cpp
|
||||
Stack.h
|
||||
StackNode.cpp
|
||||
StackNode.h
|
||||
fio.h
|
||||
fio.cpp
|
||||
)
|
||||
|
17
CPU.h
17
CPU.h
@ -64,19 +64,18 @@ public:
|
||||
return os;
|
||||
}
|
||||
|
||||
friend int key_to_index(const CPU &key, int size);
|
||||
friend int key_to_index(const CPU &key, int size) {
|
||||
std::string k = key.getCpuId();
|
||||
int sum = 0;
|
||||
for (int i = 0; k[i]; i++)
|
||||
sum += k[i];
|
||||
return sum % size;
|
||||
};
|
||||
};
|
||||
|
||||
/*~*~*~*
|
||||
Hash function: takes the key and returns the index in the hash table
|
||||
*~**/
|
||||
int key_to_index(const CPU &key, int size)
|
||||
{
|
||||
std::string k = key.getCpuId();
|
||||
int sum = 0;
|
||||
for (int i = 0; k[i]; i++)
|
||||
sum += k[i];
|
||||
return sum % size;
|
||||
};
|
||||
int key_to_index(const CPU &key, int size);
|
||||
|
||||
#endif // INC_08_TEAM_PROJECT_CPU_H
|
||||
|
202
fio.cpp
Normal file
202
fio.cpp
Normal file
@ -0,0 +1,202 @@
|
||||
#include <sstream>
|
||||
#include "fio.h"
|
||||
|
||||
bool isInteger(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;
|
||||
|
||||
int findHashSize(const string& filename) {
|
||||
ifstream inputFile(filename);
|
||||
|
||||
if (!inputFile) {
|
||||
cout << "Error opening the input file: \"" << filename << "\"" << endl;
|
||||
return -1;
|
||||
}
|
||||
cout << "Reading data from \"" << filename << "\"" << endl;
|
||||
|
||||
int count = 0;
|
||||
string line;
|
||||
while (getline(inputFile, line)) {
|
||||
if (line.size() != 0) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
count *= 2;
|
||||
|
||||
if (count < 5) {
|
||||
return 5;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
|
||||
while (!found) {
|
||||
// Every prime number occurs only 1 number before or after a multiple of six. Every other number is divisible by either 2 or 3.
|
||||
if ((count % 6) == 1) {
|
||||
count += 4;
|
||||
} else if ((count % 6) == 5) {
|
||||
count += 2;
|
||||
} else if ((count % 6) >= 2) {
|
||||
count = count - (count % 6) + 5;
|
||||
} else {
|
||||
count += 1;
|
||||
}
|
||||
|
||||
found = true;
|
||||
for (int i = 5; i < count / 2;) {
|
||||
if (count % i == 0) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
|
||||
i += 2;
|
||||
|
||||
if (count % i == 0) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
|
||||
i += 4;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void insertFile(const string& filename, BinarySearchTree<string> &bst, HashTable<CPU> &hash) {
|
||||
ifstream inputFile(filename);
|
||||
cout << "Reading data from \"" << filename << "\"" << endl;
|
||||
|
||||
if (!inputFile) {
|
||||
cout << "Error opening the input file: \"" << filename << "\"" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
string line;
|
||||
while (getline(inputFile, line)) {
|
||||
int releaseYear, coreCount;
|
||||
string name, architecture, strToNum;
|
||||
double baseClock;
|
||||
|
||||
stringstream temp(line);
|
||||
|
||||
getline(temp, name, ';');
|
||||
|
||||
temp.ignore();
|
||||
getline(temp, strToNum, ';');
|
||||
releaseYear = stoi(strToNum);
|
||||
|
||||
temp.ignore();
|
||||
getline(temp, strToNum, ';');
|
||||
coreCount = stoi(strToNum);
|
||||
|
||||
temp.ignore();
|
||||
getline(temp, architecture, ';');
|
||||
|
||||
temp.ignore();
|
||||
getline(temp, strToNum, ';');
|
||||
baseClock = stod(strToNum);
|
||||
|
||||
|
||||
// create a CPU object and initialize it with data from file
|
||||
CPU aCPU(name, releaseYear, coreCount, architecture, baseClock);
|
||||
bst.insert(name);
|
||||
|
||||
hash.insert(aCPU, key_to_index);
|
||||
}
|
||||
|
||||
inputFile.close();
|
||||
}
|
||||
|
||||
|
||||
void insertCPU(BinarySearchTree<string> &bst, HashTable<CPU> &hash) {
|
||||
string tester, name, architecture;
|
||||
int releaseYear, coreCount;
|
||||
double baseClock;
|
||||
|
||||
cout << "Please enter the name of the CPU: ";
|
||||
cin >> name;
|
||||
|
||||
CPU key(name, -1, -1, "", -1);
|
||||
CPU checker;
|
||||
|
||||
if (hash.search(checker, key, key_to_index) != -1) {
|
||||
cout << "Duplicate CPUs are not allowed!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
cout << "Please enter the year the CPU was released: ";
|
||||
cin >> tester;
|
||||
|
||||
while (!(isInteger(tester))) {
|
||||
cout << "Please enter an integer: ";
|
||||
cin >> tester;
|
||||
}
|
||||
|
||||
releaseYear = stoi(tester);
|
||||
|
||||
|
||||
cout << "Please enter the number of cores in the CPU: ";
|
||||
cin >> tester;
|
||||
|
||||
while (!(isInteger(tester))) {
|
||||
cout << "Please enter an integer: ";
|
||||
cin >> tester;
|
||||
}
|
||||
|
||||
coreCount = stoi(tester);
|
||||
|
||||
|
||||
// Strings don't need to be tested
|
||||
cout << "Please enter the architecture of the CPU: ";
|
||||
cin >> architecture;
|
||||
|
||||
|
||||
cout << "Please enter the base clock of the CPU: ";
|
||||
cin >> tester;
|
||||
|
||||
while (!(isDouble(tester))) {
|
||||
cout << "Please enter a decimal: ";
|
||||
cin >> tester;
|
||||
}
|
||||
|
||||
baseClock = stod(tester);
|
||||
|
||||
|
||||
CPU aCPU(name, releaseYear, coreCount, architecture, baseClock);
|
||||
bst.insert(name);
|
||||
|
||||
hash.insert(aCPU, key_to_index);
|
||||
}
|
||||
|
||||
bool isInteger(const string& str) {
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
if (!(isdigit(str[i]))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isDouble(const string& str) {
|
||||
int chance = 0;
|
||||
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
if (!(isdigit(str[i]))) {
|
||||
if (str[i] == '.') {
|
||||
if (chance >= 1) {
|
||||
return false;
|
||||
} else {
|
||||
chance++;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
27
fio.h
Normal file
27
fio.h
Normal file
@ -0,0 +1,27 @@
|
||||
// Unit 5: File I/O
|
||||
// - Determine hash size based on the number of records in the file
|
||||
// - Read data from the input file and insert them into the hash table and BST
|
||||
// - Save to file (in hash table sequence)
|
||||
// - Re-hashing
|
||||
//
|
||||
// Written by: Kevin Cremin
|
||||
|
||||
#ifndef INC_08_TEAM_PROJECT_FIO_H
|
||||
#define INC_08_TEAM_PROJECT_FIO_H
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "CPU.h"
|
||||
#include "HashTable.h"
|
||||
#include "BinarySearchTree.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
int findHashSize(const string& filename);
|
||||
|
||||
void insertFile(const string& filename, BinarySearchTree<string> &bst, HashTable<CPU> &hash);
|
||||
|
||||
void insertCPU(BinarySearchTree<string> &bst, HashTable<CPU> &hash);
|
||||
|
||||
#endif //INC_08_TEAM_PROJECT_FIO_H
|
149
main.cpp
149
main.cpp
@ -32,13 +32,13 @@
|
||||
#include "HashTable.h"
|
||||
#include "BinarySearchTree.h"
|
||||
#include "Stack.h"
|
||||
#include "fio.h"
|
||||
|
||||
using std::cin, std::cout, std::string, std::vector;
|
||||
|
||||
void processInput(char command, HashTable<CPU> &table, BinarySearchTree<string> &tree, Stack<CPU> &stack);
|
||||
|
||||
int main()
|
||||
{
|
||||
int main() {
|
||||
// Print help table for commands
|
||||
printHelp();
|
||||
|
||||
@ -47,18 +47,15 @@ int main()
|
||||
Stack<CPU> undoStack;
|
||||
|
||||
char command = ' ';
|
||||
while (command != 'Q')
|
||||
{
|
||||
while (command != 'Q') {
|
||||
cout << "Enter an option (H - for help): ";
|
||||
cin >> command;
|
||||
command = toupper(command, std::locale());
|
||||
// Temporary try catch block to handle unimplemented commands
|
||||
try
|
||||
{
|
||||
try {
|
||||
processInput(command, cpuTable, cpuTree, undoStack);
|
||||
}
|
||||
catch (std::logic_error &e)
|
||||
{
|
||||
catch (std::logic_error &e) {
|
||||
cout << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
@ -69,90 +66,82 @@ int main()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void insertCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree);
|
||||
void handleInsert(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree);
|
||||
|
||||
void handleFileInput(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack);
|
||||
|
||||
void deleteCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack);
|
||||
|
||||
void undoDelete(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack);
|
||||
|
||||
void processInput(char command, HashTable<CPU> &cpuTable, BinarySearchTree<string> &cpuTree, Stack<CPU> &undoStack)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case 'H':
|
||||
printHelp();
|
||||
break;
|
||||
case 'I': // Insert a new record
|
||||
insertCPU(cpuTable, cpuTree);
|
||||
break;
|
||||
case 'F': // File input: add data from a file
|
||||
throw std::logic_error("Not yet implemented: File input: add data from a file");
|
||||
break;
|
||||
case 'D': // Delete one record
|
||||
deleteCPU(cpuTable, cpuTree, undoStack);
|
||||
break;
|
||||
case 'U': // Undo delete
|
||||
undoDelete(cpuTable, cpuTree, undoStack);
|
||||
break;
|
||||
case 'L': // List all CPUs sorted by primary key
|
||||
throw std::logic_error("Not yet implemented: List all CPUs sorted by primary key");
|
||||
break;
|
||||
case 'S': // Search for a CPU by the primary key
|
||||
throw std::logic_error("Not yet implemented: Search for a CPU by the primary key");
|
||||
break;
|
||||
case 'W': // Write data to a file
|
||||
throw std::logic_error("Not yet implemented: Write data to a file");
|
||||
break;
|
||||
case 'T': // Hashtable statistics
|
||||
// throw std::logic_error("Not yet implemented: Hashtable statistics");
|
||||
cout << "Load factor: " << cpuTable.getLoadFactor() << std::endl;
|
||||
cout << "Total number of collisions: " << cpuTable.getTotalCollisions() << std::endl;
|
||||
cout << "Longest collision path: " << cpuTable.getMaxCollisions() << std::endl;
|
||||
break;
|
||||
case 'P': // Print indented tree
|
||||
throw std::logic_error("Not yet implemented: Print indented tree");
|
||||
break;
|
||||
case 'Z': // Display names of team members
|
||||
printTeam();
|
||||
break;
|
||||
case 'Q': // Quit
|
||||
break;
|
||||
default:
|
||||
cout << "Invalid command. Press 'H' to view available commands.\n";
|
||||
void processInput(char command, HashTable<CPU> &cpuTable, BinarySearchTree<string> &cpuTree, Stack<CPU> &undoStack) {
|
||||
switch (command) {
|
||||
case 'H':
|
||||
printHelp();
|
||||
break;
|
||||
case 'I': // Insert a new record
|
||||
handleInsert(cpuTable, cpuTree);
|
||||
break;
|
||||
case 'F': // File input: add data from a file
|
||||
handleFileInput(cpuTable, cpuTree, undoStack);
|
||||
break;
|
||||
case 'D': // Delete one record
|
||||
deleteCPU(cpuTable, cpuTree, undoStack);
|
||||
break;
|
||||
case 'U': // Undo delete
|
||||
undoDelete(cpuTable, cpuTree, undoStack);
|
||||
break;
|
||||
case 'L': // List all CPUs sorted by primary key
|
||||
throw std::logic_error("Not yet implemented: List all CPUs sorted by primary key");
|
||||
break;
|
||||
case 'S': // Search for a CPU by the primary key
|
||||
throw std::logic_error("Not yet implemented: Search for a CPU by the primary key");
|
||||
break;
|
||||
case 'W': // Write data to a file
|
||||
throw std::logic_error("Not yet implemented: Write data to a file");
|
||||
break;
|
||||
case 'T': // Hashtable statistics
|
||||
cout << "Load factor: " << cpuTable.getLoadFactor() << std::endl;
|
||||
cout << "Total number of collisions: " << cpuTable.getTotalCollisions() << std::endl;
|
||||
cout << "Longest collision path: " << cpuTable.getMaxCollisions() << std::endl;
|
||||
break;
|
||||
case 'P': // Print indented tree
|
||||
throw std::logic_error("Not yet implemented: Print indented tree");
|
||||
break;
|
||||
case 'Z': // Display names of team members
|
||||
printTeam();
|
||||
break;
|
||||
case 'Q': // Quit
|
||||
break;
|
||||
default:
|
||||
cout << "Invalid command. Press 'H' to view available commands.\n";
|
||||
}
|
||||
}
|
||||
|
||||
void insertCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree)
|
||||
{
|
||||
string cpuId;
|
||||
int releaseYear, coreCount;
|
||||
string architecture;
|
||||
double baseClock;
|
||||
cout << "Enter CPU ID: ";
|
||||
cin >> cpuId;
|
||||
cout << "Enter release year: ";
|
||||
cin >> releaseYear;
|
||||
cout << "Enter core count: ";
|
||||
cin >> coreCount;
|
||||
cout << "Enter architecture: ";
|
||||
cin >> architecture;
|
||||
cout << "Enter base clock: ";
|
||||
cin >> baseClock;
|
||||
CPU cpu(cpuId, releaseYear, coreCount, architecture, baseClock);
|
||||
|
||||
hashTable.insert(cpu, key_to_index);
|
||||
tree.insert(cpuId);
|
||||
void handleInsert(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree) {
|
||||
insertCPU(tree, hashTable);
|
||||
}
|
||||
|
||||
void deleteCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack)
|
||||
{
|
||||
void handleFileInput(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack) {
|
||||
string filename;
|
||||
cout << "Enter filename: ";
|
||||
cin >> filename;
|
||||
int hashSize = findHashSize(filename);
|
||||
hashTable = HashTable<CPU>(hashSize);
|
||||
tree = BinarySearchTree<string>();
|
||||
undoStack = Stack<CPU>();
|
||||
|
||||
insertFile(filename, tree, hashTable);
|
||||
cout << "Data from file \"" << filename << "\" added.\n";
|
||||
}
|
||||
|
||||
void deleteCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack) {
|
||||
string cpuId;
|
||||
cout << "Enter CPU ID to delete: ";
|
||||
cin >> cpuId;
|
||||
CPU cpu(cpuId, 0, 0, "", 0.0);
|
||||
CPU cpuFound;
|
||||
while (!hashTable.search(cpuFound, cpu, key_to_index))
|
||||
{
|
||||
while (hashTable.search(cpuFound, cpu, key_to_index) == -1) {
|
||||
cout << "CPU ID not found. Enter a valid CPU ID: ";
|
||||
cin >> cpuId;
|
||||
cpu = CPU(cpuId, 0, 0, "", 0.0);
|
||||
@ -164,10 +153,8 @@ void deleteCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<
|
||||
cout << "CPU ID \"" << cpuId << "\" deleted.\n";
|
||||
}
|
||||
|
||||
void undoDelete(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack)
|
||||
{
|
||||
if (undoStack.isEmpty())
|
||||
{
|
||||
void undoDelete(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack) {
|
||||
if (undoStack.isEmpty()) {
|
||||
cout << "No deletions to undo.\n";
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user