From 1f19d82e221b65f99bd2ba858e1278c7f42bea1a Mon Sep 17 00:00:00 2001 From: Iurii Tatishchev Date: Thu, 13 Jun 2024 17:23:30 -0700 Subject: [PATCH] initial commit --- .gitignore | 117 +++++++++++++ .idea/.gitignore | 8 + .idea/.name | 1 + .idea/08-team-project.iml | 2 + .idea/inspectionProfiles/Project_Default.xml | 6 + .idea/misc.xml | 4 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + BinarySearchTree.cpp | 1 + BinarySearchTree.h | 22 +++ BinaryTree.cpp | 1 + BinaryTree.h | 33 ++++ BinaryTreeNode.h | 11 ++ CMakeLists.txt | 24 +++ CPU.cpp | 1 + CPU.h | 65 ++++++++ HashNode.cpp | 1 + HashNode.h | 10 ++ HashTable.cpp | 1 + HashTable.h | 42 +++++ Stack.cpp | 1 + Stack.h | 29 ++++ StackNode.cpp | 1 + StackNode.h | 10 ++ main.cpp | 164 +++++++++++++++++++ utils.cpp | 71 ++++++++ utils.h | 12 ++ 27 files changed, 652 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/.name create mode 100644 .idea/08-team-project.iml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 BinarySearchTree.cpp create mode 100644 BinarySearchTree.h create mode 100644 BinaryTree.cpp create mode 100644 BinaryTree.h create mode 100644 BinaryTreeNode.h create mode 100644 CMakeLists.txt create mode 100644 CPU.cpp create mode 100644 CPU.h create mode 100644 HashNode.cpp create mode 100644 HashNode.h create mode 100644 HashTable.cpp create mode 100644 HashTable.h create mode 100644 Stack.cpp create mode 100644 Stack.h create mode 100644 StackNode.cpp create mode 100644 StackNode.h create mode 100644 main.cpp create mode 100644 utils.cpp create mode 100644 utils.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..24da4b9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,117 @@ +# Created by https://www.toptal.com/developers/gitignore/api/clion +# Edit at https://www.toptal.com/developers/gitignore?templates=clion + +### CLion ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +**/.idea/**/workspace.xml +**/.idea/**/tasks.xml +**/.idea/**/usage.statistics.xml +**/.idea/**/dictionaries +**/.idea/**/shelf + +# AWS User-specific +**/.idea/**/aws.xml + +# Generated files +**/.idea/**/contentModel.xml + +# Sensitive or high-churn files +**/.idea/**/dataSources/ +**/.idea/**/dataSources.ids +**/.idea/**/dataSources.local.xml +**/.idea/**/sqlDataSources.xml +**/.idea/**/dynamic.xml +**/.idea/**/uiDesigner.xml +**/.idea/**/dbnavigator.xml + +# Gradle +**/.idea/**/gradle.xml +**/.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +**/cmake-build-*/ + +# Mongo Explorer plugin +**/.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +**/out/ + +# mpeltonen/sbt-idea plugin +**/.idea_modules/ + +# JIRA plugin +**/atlassian-ide-plugin.xml + +# Cursive Clojure plugin +**/.idea/replstate.xml + +# SonarLint plugin +**/.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +**/com_crashlytics_export_strings.xml +**/crashlytics.properties +**/crashlytics-build.properties +**/fabric.properties + +# Editor-based Rest Client +**/.idea/httpRequests + +# Android studio 3.1+ serialized cache file +**/.idea/caches/build_file_checksums.ser + +### CLion Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +# https://plugins.jetbrains.com/plugin/7973-sonarlint +**/.idea/**/sonarlint/ + +# SonarQube Plugin +# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin +**/.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced +**/.idea/**/markdown-navigator.xml +**/.idea/**/markdown-navigator-enh.xml +**/.idea/**/markdown-navigator/ + +# Cache file creation bug +# See https://youtrack.jetbrains.com/issue/JBR-2257 +**/.idea/$CACHE_FILE$ + +# CodeStream plugin +# https://plugins.jetbrains.com/plugin/12206-codestream +**/.idea/codestream.xml + +# Azure Toolkit for IntelliJ plugin +# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij +**/.idea/**/azureSettings.xml + +# End of https://www.toptal.com/developers/gitignore/api/clion \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..831de8a --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +08_team_project \ No newline at end of file diff --git a/.idea/08-team-project.iml b/.idea/08-team-project.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/.idea/08-team-project.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..79b3c94 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..6496b10 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/BinarySearchTree.cpp b/BinarySearchTree.cpp new file mode 100644 index 0000000..909c143 --- /dev/null +++ b/BinarySearchTree.cpp @@ -0,0 +1 @@ +#include "BinarySearchTree.h" diff --git a/BinarySearchTree.h b/BinarySearchTree.h new file mode 100644 index 0000000..378f4fd --- /dev/null +++ b/BinarySearchTree.h @@ -0,0 +1,22 @@ +#ifndef INC_08_TEAM_PROJECT_BINARYSEARCHTREE_H +#define INC_08_TEAM_PROJECT_BINARYSEARCHTREE_H + +#include "BinaryTree.h" + +template +class BinarySearchTree: public BinaryTree { +private: + +public: + BinarySearchTree() : BinaryTree() {}; + + ~BinarySearchTree() { throw std::logic_error("Not implemented: ~BinarySearchTree()"); }; + + void insert(const T &item) { throw std::logic_error("Not implemented: BinarySearchTree.insert()"); }; + + void remove(const T &item) { throw std::logic_error("Not implemented: BinarySearchTree.remove()"); }; + + BinaryTreeNode *search(const T &item) { return _search(this->root, item); }; +}; + +#endif //INC_08_TEAM_PROJECT_BINARYSEARCHTREE_H diff --git a/BinaryTree.cpp b/BinaryTree.cpp new file mode 100644 index 0000000..1c97105 --- /dev/null +++ b/BinaryTree.cpp @@ -0,0 +1 @@ +#include "BinaryTree.h" diff --git a/BinaryTree.h b/BinaryTree.h new file mode 100644 index 0000000..e8ffc75 --- /dev/null +++ b/BinaryTree.h @@ -0,0 +1,33 @@ +#ifndef INC_08_TEAM_PROJECT_BINARYTREE_H +#define INC_08_TEAM_PROJECT_BINARYTREE_H + +#include "BinaryTreeNode.h" + +template +class BinaryTree { +private: + BinaryTreeNode *root; + int size; + +public: + BinaryTree() : root(nullptr), size(0) {}; + + ~BinaryTree() { throw std::logic_error("Not implemented: ~BinaryTree()"); }; + + [[nodiscard]] bool isEmpty() const { return size == 0; }; + + [[nodiscard]] int getSize() const { return size; }; + + void clear() { throw std::logic_error("Not implemented: BinaryTree.clear()"); }; + + void preOrder(void visit(const T &)) { throw std::logic_error("Not implemented: BinaryTree.preOrder()"); }; + + void postOrder(void visit(const T &)) { throw std::logic_error("Not implemented: BinaryTree.postOrder()"); }; + + void inOrder(void visit(const T &)) { throw std::logic_error("Not implemented: BinaryTree.inOrder()"); }; + + void printIndented(void visit(const T &, int)) { throw std::logic_error("Not implemented: BinaryTree.printIndented()"); }; + +}; + +#endif //INC_08_TEAM_PROJECT_BINARYTREE_H diff --git a/BinaryTreeNode.h b/BinaryTreeNode.h new file mode 100644 index 0000000..6a5945c --- /dev/null +++ b/BinaryTreeNode.h @@ -0,0 +1,11 @@ +#ifndef INC_08_TEAM_PROJECT_BINARYTREENODE_H +#define INC_08_TEAM_PROJECT_BINARYTREENODE_H + +#include + +template +class BinaryTreeNode { + +}; + +#endif //INC_08_TEAM_PROJECT_BINARYTREENODE_H diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c35554d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.28) +project(08_team_project) + +set(CMAKE_CXX_STANDARD 20) + +add_executable(08_team_project main.cpp + utils.h + utils.cpp + BinaryTreeNode.h + BinaryTree.cpp + BinaryTree.h + BinarySearchTree.cpp + BinarySearchTree.h + HashNode.cpp + HashNode.h + HashTable.cpp + HashTable.h +# CPU.cpp + CPU.h + Stack.cpp + Stack.h + StackNode.cpp + StackNode.h +) diff --git a/CPU.cpp b/CPU.cpp new file mode 100644 index 0000000..3971715 --- /dev/null +++ b/CPU.cpp @@ -0,0 +1 @@ +#include "CPU.h" diff --git a/CPU.h b/CPU.h new file mode 100644 index 0000000..ff3c6c1 --- /dev/null +++ b/CPU.h @@ -0,0 +1,65 @@ +#ifndef INC_08_TEAM_PROJECT_CPU_H +#define INC_08_TEAM_PROJECT_CPU_H + + +#include + +class CPU { +private: + std::string cpuId; + int releaseYear; + int coreCount; + std::string architecture; + double baseClock; + +public: + CPU(std::string id, int year, int cores, std::string arch, double clock) : + cpuId(std::move(id)), + releaseYear(year), + coreCount(cores), + architecture(std::move(arch)), + baseClock(clock) {}; + + std::string getCpuId() const; + + int getReleaseYear() const; + + int getCoreCount() const; + + std::string getArchitecture() const; + + double getBaseClock() const; + + void setCpuId(std::string id); + + void setReleaseYear(int year); + + void setCoreCount(int cores); + + void setArchitecture(std::string arch); + + void setBaseClock(double clock); + + // Operator overloads + bool operator<(const CPU &rhs) const; + + bool operator>(const CPU &rhs) const; + + bool operator==(const CPU &rhs) const; + + // Friend function declarations + friend void display(const CPU &cpu); + + friend void iDisplay(const CPU &cpu, int level); + + friend std::ostream &operator<<(std::ostream &os, const CPU &cpu); + + friend int key_to_index(const CPU &key, int size); +}; + +int key_to_index(const CPU &key, int size) { + // TODO + return key.coreCount % size; +}; + +#endif //INC_08_TEAM_PROJECT_CPU_H diff --git a/HashNode.cpp b/HashNode.cpp new file mode 100644 index 0000000..6e7a116 --- /dev/null +++ b/HashNode.cpp @@ -0,0 +1 @@ +#include "HashNode.h" diff --git a/HashNode.h b/HashNode.h new file mode 100644 index 0000000..6a49583 --- /dev/null +++ b/HashNode.h @@ -0,0 +1,10 @@ +#ifndef INC_08_TEAM_PROJECT_HASHNODE_H +#define INC_08_TEAM_PROJECT_HASHNODE_H + +template +class HashNode { + +}; + + +#endif //INC_08_TEAM_PROJECT_HASHNODE_H diff --git a/HashTable.cpp b/HashTable.cpp new file mode 100644 index 0000000..dc7a1cc --- /dev/null +++ b/HashTable.cpp @@ -0,0 +1 @@ +#include "HashTable.h" diff --git a/HashTable.h b/HashTable.h new file mode 100644 index 0000000..b047e75 --- /dev/null +++ b/HashTable.h @@ -0,0 +1,42 @@ +#ifndef INC_08_TEAM_PROJECT_HASHTABLE_H +#define INC_08_TEAM_PROJECT_HASHTABLE_H + +#include +#include "HashNode.h" + +template +class HashTable { +private: + int hashSize; + int count; + HashNode *hashAry; + +public: + HashTable() : hashSize(97), count(0) { + hashAry = new HashNode[hashSize]; + }; + + ~HashTable() { delete[] hashAry; }; + + [[nodiscard]] int getCount() const { return count; }; + + [[nodiscard]] int getHashSize() const { return hashSize; }; + + bool isEmpty() const { return count == 0; }; + + bool isFull() const { return count == hashSize; }; + + double getLoadFactor() const { throw std::logic_error("Not implemented: HashTable.getLoadFactor()"); }; + + bool insert(const T &item, int h(const T&, int)) { throw std::logic_error("Not implemented: HashTable.insert()"); }; + + bool remove(const T &item, int h(const T&), int) { throw std::logic_error("Not implemented: HashTable.remove()"); }; + + bool search(const T &item, int h(const T&), int) { throw std::logic_error("Not implemented: HashTable.search()"); }; + + int getTotalCollisions() const { throw std::logic_error("Not implemented: HashTable.getTotalCollisions()"); }; + + int getMaxCollisions() const { throw std::logic_error("Not implemented: HashTable.getMaxCollisions()"); }; +}; + +#endif //INC_08_TEAM_PROJECT_HASHTABLE_H diff --git a/Stack.cpp b/Stack.cpp new file mode 100644 index 0000000..25cd86c --- /dev/null +++ b/Stack.cpp @@ -0,0 +1 @@ +#include "Stack.h" diff --git a/Stack.h b/Stack.h new file mode 100644 index 0000000..c02b59a --- /dev/null +++ b/Stack.h @@ -0,0 +1,29 @@ +#ifndef INC_08_TEAM_PROJECT_STACK_H +#define INC_08_TEAM_PROJECT_STACK_H + +#include +#include "StackNode.h" + +template +class Stack { +private: + StackNode *top; + int count; + +public: + Stack() : top(nullptr), count(0) {}; + + ~Stack() { throw std::logic_error("Not implemented: ~Stack()"); }; + + [[nodiscard]] bool isEmpty() const { return count == 0; }; + + [[nodiscard]] int getCount() const { return count; }; + + void push(const T &data) { throw std::logic_error("Not implemented: Stack.push()"); }; + + T pop() { throw std::logic_error("Not implemented: Stack.pop()"); }; + + T peek() { throw std::logic_error("Not implemented: Stack.peek()"); }; +}; + +#endif //INC_08_TEAM_PROJECT_STACK_H diff --git a/StackNode.cpp b/StackNode.cpp new file mode 100644 index 0000000..a0bb713 --- /dev/null +++ b/StackNode.cpp @@ -0,0 +1 @@ +#include "StackNode.h" diff --git a/StackNode.h b/StackNode.h new file mode 100644 index 0000000..4ad0b2a --- /dev/null +++ b/StackNode.h @@ -0,0 +1,10 @@ +#ifndef INC_08_TEAM_PROJECT_STACKNODE_H +#define INC_08_TEAM_PROJECT_STACKNODE_H + +template +class StackNode { + +}; + + +#endif //INC_08_TEAM_PROJECT_STACKNODE_H diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..991e8ab --- /dev/null +++ b/main.cpp @@ -0,0 +1,164 @@ +// # Project Requirements +// +// Begin by displaying some general information about the project, the names and tasks of the developers. +// Processing is to be menu-driven with the following options: +// +// - Add a new data item. +// - Add data from an input file (get the name of the input file from the user). (does it overwrite?) +// - Delete data (one item). +// - Find and display one element using the primary key. +// - List data sorted by the primary key. +// - Hidden print option (do not show it in the menu: details are given in Team Project- Part2). +// - display the indented tree +// - Write data to a file. +// - Statistics (details are given in Team Project-Part2) +// - load factor +// - number of collisions (total) +// - longest collision path +// - Hidden option (do not show it in the menu): when selected, display the names of the team members. +// - Help – to show the menu. Show the menu once, before the loop, then show the menu upon request: “Enter an option (H – for help): ” +// - Exit +// +// At the end of the program, the data are to be automatically written to a file. +// This is in addition to the menu write file option. +// The output file name does not have to be the same as the input file name, +// but the file format must be the same so that it can be read back into the program. + +#include +#include +#include +#include "utils.h" +#include "CPU.h" +#include "HashTable.h" +#include "BinarySearchTree.h" +#include "Stack.h" + +using std::cin, std::cout, std::string, std::vector; + +void printHelp() { + static const vector helpWidths = {5, 40}; + static const vector> helpData = { + {"Key", "Command"}, + {"H", "Help"}, + {"I", "Insert a new record"}, + {"F", "File input: add data from a file"}, + {"D", "Delete one record"}, + {"U", "Undo delete"}, + {"L", "List all CPUs sorted by primary key"}, + {"S", "Search for a CPU by the primary key"}, + {"W", "Write data to a file"}, + {"T", "Hashtable statistics"}, + {"Q", "Quit"}, + {"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)"}, + }; + printTable(helpWidths, helpData); +} + +void printTeam() { + static const vector teamWidths = {40}; + static const vector> teamData = { + {"Team Members"}, + {"Kevin Cremin"}, + {"Kevin Galvan Serrano"}, + {"Joshiro Lawrence"}, + {"Tuhin Mondal"}, + {"Iurii Tatishchev"}, + }; + printTable(teamWidths, teamData); +} + +void processInput(char command, HashTable& table, BinarySearchTree& tree, Stack& stack); + +CPU readCPUInfo(); + +int main() { + // Print help table for commands + printHelp(); + + HashTable cpuTable; + BinarySearchTree cpuTree; + Stack undoStack; + + char command = ' '; + while (command != 'Q') { + cout << "Enter an option (H - for help): "; + cin >> command; + // Temporary try catch block to handle unimplemented commands + try { + processInput(toupper(command, std::locale()), cpuTable, cpuTree, undoStack); + } catch (std::logic_error& e) { + cout << e.what() << '\n'; + } + } + // Quit command received + // TODO: Write data to a file + cout << "Exiting program...\n"; + + return 0; +} + +void insertCPU(HashTable &hashTable, BinarySearchTree &tree); + +void processInput(char command, HashTable &cpuTable, BinarySearchTree &cpuTree, Stack &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 + throw std::logic_error("Not yet implemented: Delete one record"); + break; + case 'U': // Undo delete + throw std::logic_error("Not yet implemented: Undo delete"); + 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"); + 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 &hashTable, BinarySearchTree &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(cpu); +} diff --git a/utils.cpp b/utils.cpp new file mode 100644 index 0000000..8ba08b3 --- /dev/null +++ b/utils.cpp @@ -0,0 +1,71 @@ +#include +#include "utils.h" +using std::cout; + +void printRow(const vector &widths, const vector& row) { + cout << '|'; + for (int i = 0; i < widths.size(); i++) { + cout << ' '; + cout.width(widths[i] - 1); + cout << std::left << row[i]; + cout << '|'; + } + cout << '\n'; +}; + +/* + * Print ascii/unicode table with given column widths and data. For example: + * ┌────────────────────────────────────────┬──────────┬────────────────────────┬────────────────┐ + * | Col1 | Col2 | Col3 | Numeric Column | + * +========================================+==========+========================+================+ + * | Value 1 | Value 2 | 123 | 10.0 | + * | Separate | cols | with a tab or 4 spaces | -2,027.1 | + * | This is a row with only one cell | | | | + * └────────────────────────────────────────┴──────────┴────────────────────────┴────────────────┘ + */ +void printTable(const vector& widths, const vector>& data) { + // Print top border + cout << "┌"; + for (int width : widths) { + for (int i = 0; i < width; i++) { + cout << "─"; + } + cout << "┬"; + } + cout << "\b┐\n"; + + // Print header + cout << '|'; + for (int i = 0; i < widths.size(); i++) { + cout << ' '; + cout.width(widths[i] - 1); + cout << std::left << data[0][i]; + cout << '|'; + } + cout << '\n'; + + // Print middle border + cout << '+'; + for (int width : widths) { + for (int i = 0; i < width; i++) { + cout << '='; + } + cout << '+'; + } + cout << '\n'; + + // Print data + for (int i = 1; i < data.size(); i++) { + printRow(widths, data[i]); + } + + // Print bottom border + cout << "└"; + for (int width : widths) { + for (int i = 0; i < width; i++) { + cout << "─"; + } + cout << "┴"; + } + cout << "\b┘\n"; +} diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..395bd18 --- /dev/null +++ b/utils.h @@ -0,0 +1,12 @@ +#ifndef INC_08_TEAM_PROJECT_UTILS_H +#define INC_08_TEAM_PROJECT_UTILS_H + +#include +#include +using std::vector, std::string; + +void printRow(const vector &widths, const vector& row); + +void printTable(const vector& widths, const vector>& data); + +#endif //INC_08_TEAM_PROJECT_UTILS_H