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"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="CMakePythonSetting">
|
||||||
|
<option name="pythonIntegrationState" value="YES" />
|
||||||
|
</component>
|
||||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||||
</project>
|
</project>
|
@ -18,4 +18,6 @@ add_executable(08_team_project main.cpp
|
|||||||
Stack.h
|
Stack.h
|
||||||
StackNode.cpp
|
StackNode.cpp
|
||||||
StackNode.h
|
StackNode.h
|
||||||
|
fio.h
|
||||||
|
fio.cpp
|
||||||
)
|
)
|
||||||
|
17
CPU.h
17
CPU.h
@ -64,19 +64,18 @@ public:
|
|||||||
return os;
|
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
|
Hash function: takes the key and returns the index in the hash table
|
||||||
*~**/
|
*~**/
|
||||||
int key_to_index(const CPU &key, int size)
|
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // INC_08_TEAM_PROJECT_CPU_H
|
#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 "HashTable.h"
|
||||||
#include "BinarySearchTree.h"
|
#include "BinarySearchTree.h"
|
||||||
#include "Stack.h"
|
#include "Stack.h"
|
||||||
|
#include "fio.h"
|
||||||
|
|
||||||
using std::cin, std::cout, std::string, std::vector;
|
using std::cin, std::cout, std::string, std::vector;
|
||||||
|
|
||||||
void processInput(char command, HashTable<CPU> &table, BinarySearchTree<string> &tree, Stack<CPU> &stack);
|
void processInput(char command, HashTable<CPU> &table, BinarySearchTree<string> &tree, Stack<CPU> &stack);
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
// Print help table for commands
|
// Print help table for commands
|
||||||
printHelp();
|
printHelp();
|
||||||
|
|
||||||
@ -47,18 +47,15 @@ int main()
|
|||||||
Stack<CPU> undoStack;
|
Stack<CPU> undoStack;
|
||||||
|
|
||||||
char command = ' ';
|
char command = ' ';
|
||||||
while (command != 'Q')
|
while (command != 'Q') {
|
||||||
{
|
|
||||||
cout << "Enter an option (H - for help): ";
|
cout << "Enter an option (H - for help): ";
|
||||||
cin >> command;
|
cin >> command;
|
||||||
command = toupper(command, std::locale());
|
command = toupper(command, std::locale());
|
||||||
// Temporary try catch block to handle unimplemented commands
|
// Temporary try catch block to handle unimplemented commands
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
processInput(command, cpuTable, cpuTree, undoStack);
|
processInput(command, cpuTable, cpuTree, undoStack);
|
||||||
}
|
}
|
||||||
catch (std::logic_error &e)
|
catch (std::logic_error &e) {
|
||||||
{
|
|
||||||
cout << e.what() << '\n';
|
cout << e.what() << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,90 +66,82 @@ int main()
|
|||||||
return 0;
|
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 deleteCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack);
|
||||||
|
|
||||||
void undoDelete(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)
|
void processInput(char command, HashTable<CPU> &cpuTable, BinarySearchTree<string> &cpuTree, Stack<CPU> &undoStack) {
|
||||||
{
|
switch (command) {
|
||||||
switch (command)
|
case 'H':
|
||||||
{
|
printHelp();
|
||||||
case 'H':
|
break;
|
||||||
printHelp();
|
case 'I': // Insert a new record
|
||||||
break;
|
handleInsert(cpuTable, cpuTree);
|
||||||
case 'I': // Insert a new record
|
break;
|
||||||
insertCPU(cpuTable, cpuTree);
|
case 'F': // File input: add data from a file
|
||||||
break;
|
handleFileInput(cpuTable, cpuTree, undoStack);
|
||||||
case 'F': // File input: add data from a file
|
break;
|
||||||
throw std::logic_error("Not yet implemented: File input: add data from a file");
|
case 'D': // Delete one record
|
||||||
break;
|
deleteCPU(cpuTable, cpuTree, undoStack);
|
||||||
case 'D': // Delete one record
|
break;
|
||||||
deleteCPU(cpuTable, cpuTree, undoStack);
|
case 'U': // Undo delete
|
||||||
break;
|
undoDelete(cpuTable, cpuTree, undoStack);
|
||||||
case 'U': // Undo delete
|
break;
|
||||||
undoDelete(cpuTable, cpuTree, undoStack);
|
case 'L': // List all CPUs sorted by primary key
|
||||||
break;
|
throw std::logic_error("Not yet implemented: List all CPUs sorted by primary key");
|
||||||
case 'L': // List all CPUs sorted by primary key
|
break;
|
||||||
throw std::logic_error("Not yet implemented: List all CPUs sorted by primary key");
|
case 'S': // Search for a CPU by the primary key
|
||||||
break;
|
throw std::logic_error("Not yet implemented: Search for a CPU by the primary key");
|
||||||
case 'S': // Search for a CPU by the primary key
|
break;
|
||||||
throw std::logic_error("Not yet implemented: Search for a CPU by the primary key");
|
case 'W': // Write data to a file
|
||||||
break;
|
throw std::logic_error("Not yet implemented: Write data to a file");
|
||||||
case 'W': // Write data to a file
|
break;
|
||||||
throw std::logic_error("Not yet implemented: Write data to a file");
|
case 'T': // Hashtable statistics
|
||||||
break;
|
cout << "Load factor: " << cpuTable.getLoadFactor() << std::endl;
|
||||||
case 'T': // Hashtable statistics
|
cout << "Total number of collisions: " << cpuTable.getTotalCollisions() << std::endl;
|
||||||
// throw std::logic_error("Not yet implemented: Hashtable statistics");
|
cout << "Longest collision path: " << cpuTable.getMaxCollisions() << std::endl;
|
||||||
cout << "Load factor: " << cpuTable.getLoadFactor() << std::endl;
|
break;
|
||||||
cout << "Total number of collisions: " << cpuTable.getTotalCollisions() << std::endl;
|
case 'P': // Print indented tree
|
||||||
cout << "Longest collision path: " << cpuTable.getMaxCollisions() << std::endl;
|
throw std::logic_error("Not yet implemented: Print indented tree");
|
||||||
break;
|
break;
|
||||||
case 'P': // Print indented tree
|
case 'Z': // Display names of team members
|
||||||
throw std::logic_error("Not yet implemented: Print indented tree");
|
printTeam();
|
||||||
break;
|
break;
|
||||||
case 'Z': // Display names of team members
|
case 'Q': // Quit
|
||||||
printTeam();
|
break;
|
||||||
break;
|
default:
|
||||||
case 'Q': // Quit
|
cout << "Invalid command. Press 'H' to view available commands.\n";
|
||||||
break;
|
|
||||||
default:
|
|
||||||
cout << "Invalid command. Press 'H' to view available commands.\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void insertCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree)
|
void handleInsert(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree) {
|
||||||
{
|
insertCPU(tree, hashTable);
|
||||||
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 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;
|
string cpuId;
|
||||||
cout << "Enter CPU ID to delete: ";
|
cout << "Enter CPU ID to delete: ";
|
||||||
cin >> cpuId;
|
cin >> cpuId;
|
||||||
CPU cpu(cpuId, 0, 0, "", 0.0);
|
CPU cpu(cpuId, 0, 0, "", 0.0);
|
||||||
CPU cpuFound;
|
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: ";
|
cout << "CPU ID not found. Enter a valid CPU ID: ";
|
||||||
cin >> cpuId;
|
cin >> cpuId;
|
||||||
cpu = CPU(cpuId, 0, 0, "", 0.0);
|
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";
|
cout << "CPU ID \"" << cpuId << "\" deleted.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void undoDelete(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack)
|
void undoDelete(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack) {
|
||||||
{
|
if (undoStack.isEmpty()) {
|
||||||
if (undoStack.isEmpty())
|
|
||||||
{
|
|
||||||
cout << "No deletions to undo.\n";
|
cout << "No deletions to undo.\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user