Skip to main content
Rollback to Revision 5
Source Link
Toby Speight
  • 81.7k
  • 14
  • 101
  • 308

enter image description hereenter image description here enter image description here

#ifndef CONSOLETABLE_CONSOLETABLE_H
#define CONSOLETABLE_CONSOLETABLE_H

#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <memory>
#include "ConsoleTableRow.h"
#include "ConsoleTableUtils.h"
#include <sstream>

enum class TableStyle {
    BASIC,
    LINED,
    DOUBLE_LINE,
};

enum class Separator HorizontalSeperator{
    TOPSEPERATOR_TOP,
    MIDDLESEPERATOR_MIDDLE,
    BOTTOMSEPERATOR_BOTTOM
};
 
typedef std::vector<std::string> Columns;
typedef std::vector<ConsoleTableRow> Rows;


class ConsoleTable {
public:

    /// Create a new ConsoleTable
    /// \param(TableStyle style The design of the console table);
    /// \param padding Additional space between the text and the cell border
    explicitvoid ConsoleTablesetPadding(TableStyle style, unsigned int paddingwidth);
 
    /// Add a new column to the ConsoleTable
    /// \param name The name of the column
    void addColumn(std::string name);
 
    /// Add a new row with information into the ConsoleTable
    /// \param item The ConsoleTableRow which should be added
    void addRow(ConsoleTableRow item*item);
 
    /// Remove a row from the ConsoleTable at the given index
    /// \param index The index of the row which should be removed
    /// \return True if row was removed successfully, otherwise false
    bool removeRow(int index);

    /// Update the information in specific cell of a row
    /// \param data The new data that should be set
    /// \param row The index of the row which should be updated
    /// \param col The index of the column that should be updated
    /// \return True if the update was successful, otherwise false
    bool editRow(std::string data, int row, int col);

    /// Displays the table with columns and all content
    void printTable();

private:

    /// Additional space between cell border and cell text
    unsigned int padding = 1;

    /// Vector of all columns of the ConsoleTable
    Columnsstd::vector<std::string> columns;
 
    /// Vector of all rows instd::vector<ConsoleTableRow the*> ConsoleTableentries;
    RowsConsoleTableUtils* rows;utils;

    // Table Style variables
    std::string style_line_horizontal;
    std::string style_line_vertical;
    std::string style_line_cross;
    std::string style_t_intersect_right;
    std::string style_t_intersect_left;
    std::string style_t_intersect_top;
    std::string style_t_intersect_bottom;
    std::string style_edge_top_left;style_edge_topleft;
    std::string style_edge_top_right;style_edge_topright;
    std::string style_edge_bottom_left;style_edge_buttomleft;
    std::string style_edge_bottom_right;

    /// Prints the horizontal seperator lines for the table
    /// \param maxWidths A vector that holds the maximum of all items in each column
    /// \param separator Defines what kind of seperator is used (Top, Middle, Bottom)style_edge_buttomright;
    /// \param invisibleRowLines If true seperator lines are only used between column headers and the first row, otherwise between every row
    void printSeparatorprintHorizontalSeperator(const std::vector<int> &maxWidths, Separator separator,
                        boolHorizontalSeperator invisibleRowLinesseperator) const;

    /// Sets the design for the ConsoleTable
    /// \param style The style of the ConsoleTable (BASIC, LINED, DOUBLELINED)
    void setTableStyle(TableStyle style);

};


#endif //CONSOLETABLE_CONSOLETABLE_H
#include "ConsoleTable.h"


ConsoleTable::ConsoleTable(TableStyle style, unsigned int padding) {
    setTableStyle(style);
    this->padding>utils = padding;new ConsoleTableUtils();
}

void ConsoleTable::addColumn(std::string name) {
    columnsthis->columns.push_back(name);
}

void ConsoleTable::printTable() {

    // Calculate column maxima
    std::vector<int> maxWidths(columnsthis->columns.size());
    for (autoint &entryrow := rows0; row < this->entries.size(); row++) {
        for (int col = 0; col < columnsthis->columns.size(); col++) {
            std::string cellText = entry.getEntry().atthis->entries[row]->getEntry(col);[col];
            if (columns.at(col)this->columns[col].length() > maxWidths.at(col)maxWidths[col])
                maxWidths.at(col)maxWidths[col] = columns.at(col)this->columns[col].length();
            if (maxWidths.at(col)maxWidths[col] < cellText.length()) {
                maxWidths.at(col)maxWidths[col] = cellText.length();
            }
        }
    }

    printSeparatorprintHorizontalSeperator(maxWidths, Separator::TOP, falseSEPERATOR_TOP);

    // Print column values
    for (int col = 0; col < columnsthis->columns.size(); col++) {
        std::string cellText = columns.at(col);this->columns[col];
        int len = cellText.length();
        std::string paddedText = cellText + std::string(maxWidths.at(col)maxWidths[col] - len, ' ');
        std::cout << style_line_verticalthis->style_line_vertical << std::string(paddingthis->padding, ' ') << paddedText
                  << std::string(paddingthis->padding, ' ');
        std::cout << (col == columnsthis->columns.size() - 1 ? style_line_verticalthis->style_line_vertical + "\n" : "");
    }

    printSeparatorprintHorizontalSeperator(maxWidths, Separator::MIDDLE, falseSEPERATOR_MIDDLE);

    // Print cell values
    for (int row = 0; row < rowsthis->entries.size(); row++) {
        for (int col = 0; col < columnsthis->columns.size(); col++) {
            std::string cellText = rows.at(row).getEntry().atthis->entries[row]->getEntry(col);[col];
            std::string paddedText = cellText + std::string(maxWidths.at(col)maxWidths[col] - cellText.length(), ' ');
            std::cout << style_line_verticalthis->style_line_vertical << std::string(paddingthis->padding, ' ') << paddedText
                      << std::string(paddingthis->padding, ' ');
        }
        std::cout << style_line_verticalthis->style_line_vertical << std::endl;
        if (row == rowsthis->entries.size() - 1)
            printSeparatorprintHorizontalSeperator(maxWidths, Separator::BOTTOM, falseSEPERATOR_BOTTOM);
        else
            printSeparatorprintHorizontalSeperator(maxWidths, Separator::MIDDLE, trueSEPERATOR_MIDDLE);
    }
}

void ConsoleTable::printSeparatorprintHorizontalSeperator(const std::vector<int> &maxWidths, Separator separator,
                                  boolHorizontalSeperator invisibleRowLinesseperator) const {
    for (int col = 0; col < columns.size(); ++col) {

        switch (separator) {
            case Separator::TOP:{
                std::cout << (col == 0 ? style_edge_top_left : "");
                break;
            }
            case Separator::MIDDLE:{
                if (invisibleRowLines)
                    continue;
                std::cout << (col == 0 ? style_t_intersect_left : "");
                break;
            }
            case Separator::BOTTOM:{
                std::cout << (col == 0 ? style_edge_bottom_left : "");
                break;
            }
        }

        switch (seperator) {
            case SEPERATOR_TOP: {
                std::cout << ConsoleTableUtils::repeatString(style_line_horizontal,col padding== 0 ? this->style_edge_topleft : "");
                std::cout << ConsoleTableUtils::repeatStringutils->repeatString(style_line_horizontalthis->style_line_horizontal, maxWidths.at(col)this->padding);
                std::cout << ConsoleTableUtils::repeatStringutils->repeatString(style_line_horizontalthis->style_line_horizontal, paddingmaxWidths[col]);
 
        switch        std::cout << utils->repeatString(separator)this->style_line_horizontal, {this->padding);
            case Separator   std::TOPcout << (col != columns.size() - 1 ? this->style_t_intersect_top : {this->style_edge_topright);
                std::cout << (col !=== columns.size() - 1 ? style_t_intersect_top"\n" : style_edge_top_right"");
                break;
            }
            case SeparatorSEPERATOR_MIDDLE: {
                std:MIDDLE:cout {<< (col == 0 ? this->style_t_intersect_left : "");
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << utils->repeatString(this->style_line_horizontal, maxWidths[col]);
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << (col != columns.size() - 1 ? style_line_crossthis->style_line_cross : style_t_intersect_rightthis->style_t_intersect_right);
                std::cout << (col == columns.size() - 1 ? "\n" : "");
                break;
            }
            case SeparatorSEPERATOR_BOTTOM: {
                std:BOTTOM:cout {<< (col == 0 ? this->style_edge_buttomleft : "");
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << utils->repeatString(this->style_line_horizontal, maxWidths[col]);
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout
                        << (col != columns.size() - 1 ? style_t_intersect_bottomthis->style_t_intersect_bottom : style_edge_bottom_rightthis->style_edge_buttomright);
                std::cout << (col == columns.size() - 1 ? "\n" : "");
                break;
            }
        }

        std::cout << (col == columns.size() - 1 ? "\n" : "");

    }
}

void ConsoleTable::addRow(ConsoleTableRow item*item) {
    rowsthis->entries.push_back(item);
}

bool ConsoleTable::removeRow(int index) {
    if (index > rowsthis->entries.size())
        return false;
    rowsthis->entries.erase(rowsthis->entries.begin() + index);
    return true;
}

bool ConsoleTable::editRow(std::string data, int row, int col) {
    if (row > rowsthis->entries.size())
        return false;

    if (col > columnsthis->columns.size())
        return false;

    auto entry = rows.at(row);this->entries[row];
    entry.editEntry->editEntry(data, col);
    return true;
}

void ConsoleTable::setPadding(unsigned int width) {
    this->padding = width;
}

void ConsoleTable::setTableStyle(TableStyle style) {
    switch (style) {
        case TableStyle::BASIC: {
            style_line_horizontalthis->style_line_horizontal = "-";
            style_line_verticalthis->style_line_vertical = "|";
            style_line_crossthis->style_line_cross = "+";

            style_t_intersect_rightthis->style_t_intersect_right = "+";
            style_t_intersect_leftthis->style_t_intersect_left = "+";
            style_t_intersect_topthis->style_t_intersect_top = "+";
            style_t_intersect_bottomthis->style_t_intersect_bottom = "+";

            style_edge_top_leftthis->style_edge_topleft = "+";
            style_edge_top_rightthis->style_edge_topright = "+";
            style_edge_bottom_leftthis->style_edge_buttomleft = "+";
            style_edge_bottom_rightthis->style_edge_buttomright = "+";
            break;
        }
        case TableStyle::LINED: {
            style_line_horizontalthis->style_line_horizontal = "━";
            style_line_verticalthis->style_line_vertical = "┃";
            style_line_crossthis->style_line_cross = "╋";

            style_t_intersect_rightthis->style_t_intersect_right = "┫";
            style_t_intersect_leftthis->style_t_intersect_left = "┣";
            style_t_intersect_topthis->style_t_intersect_top = "┳";
            style_t_intersect_bottomthis->style_t_intersect_bottom = "┻";

            style_edge_top_leftthis->style_edge_topleft = "┏";
            style_edge_top_rightthis->style_edge_topright = "┓";
            style_edge_bottom_leftthis->style_edge_buttomleft = "┗";
            style_edge_bottom_rightthis->style_edge_buttomright = "┛";
            break;
        }
        case TableStyle::DOUBLE_LINE: {
            style_line_horizontalthis->style_line_horizontal = "═";
            style_line_verticalthis->style_line_vertical = "║";
            style_line_crossthis->style_line_cross = "╬";

            style_t_intersect_rightthis->style_t_intersect_right = "╣";
            style_t_intersect_leftthis->style_t_intersect_left = "╠";
            style_t_intersect_topthis->style_t_intersect_top = "╦";
            style_t_intersect_bottomthis->style_t_intersect_bottom = "╩";

            style_edge_top_leftthis->style_edge_topleft = "╔";
            style_edge_top_rightthis->style_edge_topright = "╗";
            style_edge_bottom_leftthis->style_edge_buttomleft = "╚";
            style_edge_bottom_rightthis->style_edge_buttomright = "╝";
            break;
        }
    }
}
#ifndef CONSOLETABLE_CONSOLETABLEROW_HCONSOLETABLE_CONSOLETABLEENTRY_H
#define CONSOLETABLE_CONSOLETABLEROW_HCONSOLETABLE_CONSOLETABLEENTRY_H

#include <string>
#include <vector>

class ConsoleTableRow {
public:
 
    /// Create a new ConsoleTableRow
    /// \param width How many cells does the row have
    explicit ConsoleTableRow(int width);
 
    /// Add a new cell to the ConsoleTableRow
    /// \param data The data of the new cell
    /// \param column The column index of the new cell
    void addEntry(std::string data, int column);

    /// Updates a cell in the ConsoleTableRow with new data
    /// \param data The new data that should be updated
    /// \param column The index of the column that should be updated
    void editEntry(std::string data, int column);

    /// Returns the ConsoleTableRow
    /// \return The vector which holds all entries of the ConsoleTableRow
    std::vector <std::string> getEntry() const&;;

private:

    /// The vector which holds all entries of the ConsoleTableRow
    std::vector <std::string> row;
 
};


#endif //CONSOLETABLE_CONSOLETABLEROW_HCONSOLETABLE_CONSOLETABLEENTRY_H
#include "ConsoleTableRow.h"

ConsoleTableRow::ConsoleTableRow(int width) {
    rowthis->row.resize(width);
}

void ConsoleTableRow::addEntry(std::string data, int column) {
    row.at(column)row[column] = data;
}

std::vector<std::string> ConsoleTableRow::getEntry() const&{
    return row;this->row;
}

void ConsoleTableRow::editEntry(std::string data, int column) {
    row.at(column)this->row[column] = data;
}
#ifndef CONSOLETABLE_CONSOLETABLEUTILS_H
#define CONSOLETABLE_CONSOLETABLEUTILS_H

#include <string>
#include <sstream>

class ConsoleTableUtils {
public:

    /// Repeats a given string n times
    /// \param input The string which should be repeated
    /// \param n How many times should the given string be repeated
    /// \return The repeated string
    static std::string repeatString(const std::string &inputinput, int n){
        std::ostringstream os;
        for (int i = 0; i < n; i++)
            os << input;
        return os.str();
    }const;

}; 


#endif //CONSOLETABLE_CONSOLETABLEUTILS_H

##ConsoleTableUtils.cpp

#include "ConsoleTableUtils.h"

std::string ConsoleTableUtils::repeatString(std::string input, int n) const {
    std::ostringstream os;
    for (int i = 0; i < n; i++)
        os << input;
    return os.str();
}
#include <iostream>
#include <unistd.h>
#include "ConsoleTable.h"

int main() { 

    ConsoleTable ct(TableStyle::BASIC, 2);
 
    ct.addColumnsetPadding("Country"1); 

    ct.addColumn("Capital""Country");
    ct.addColumn("Population""Name");
    ct.addColumn("Area""Profession");
    ct.addColumn("Currency""Age");

    ConsoleTableRowauto row1entry = new ConsoleTableRow(54);
    row1.addEntryentry->addEntry("Germany", 0);
    row1.addEntryentry->addEntry("Berlin""Michael", 1);
    row1.addEntryentry->addEntry("82,800,000""Computer Engineer", 2);
    row1.addEntryentry->addEntry("357,168 km2""19", 3);
    row1.addEntry("Euro", 4);
    ct.addRow(row1entry);

    auto ConsoleTableRowentry2 row2= new ConsoleTableRow(54);
    row2.addEntryentry2->addEntry("Australia""England", 0);
    row2.addEntryentry2->addEntry("Canberra""Robert", 1);
    row2.addEntryentry2->addEntry("24,877,800""Artist", 2);
    row2.addEntryentry2->addEntry("7,692,024 km2""34", 3);
    row2ct.addEntryaddRow("Australian Dollar", 4entry2); 

    ct.addRow(row2);

auto entry3 = new ConsoleTableRow row3(54);
    row3.addEntryentry3->addEntry("China""United Kingdom", 0);
    row3.addEntryentry3->addEntry("Beijing""Julia", 1);
    row3.addEntryentry3->addEntry("1,403,500,365""Designer", 2);
    row3.addEntryentry3->addEntry("9,596,961 km2""42", 3);
    row3ct.addEntryaddRow("Yuan", 4entry3); 

    ct.addRow(row3);

auto entry4 = new ConsoleTableRow row4(54);
    row4.addEntryentry4->addEntry("Iceland""United Staates", 0);
    row4.addEntryentry4->addEntry("Reykjavik""Jo", 1);
    row4.addEntryentry4->addEntry("348,580""Actor", 2);
    row4.addEntryentry4->addEntry("102,775 km2""21", 3);
    row4.addEntry("Icelandic Krona", 4);
    ct.addRow(row4entry4);

    // Print all rows
    ct.printTable();

    sleep(1);

    // Remove entry
    ct.removeRow(1);
    ct.printTable();

    sleep(1);

    // Update entry
    ct.editRow("New Country!",0, 1);entries
    ct.printTable();

    return 0;
}   

enter image description here

#ifndef CONSOLETABLE_CONSOLETABLE_H
#define CONSOLETABLE_CONSOLETABLE_H

#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <memory>
#include "ConsoleTableRow.h"
#include "ConsoleTableUtils.h"


enum class TableStyle {
    BASIC,
    LINED,
    DOUBLE_LINE,
};

enum class Separator {
    TOP,
    MIDDLE,
    BOTTOM
};
 
typedef std::vector<std::string> Columns;
typedef std::vector<ConsoleTableRow> Rows;


class ConsoleTable {
public:

    /// Create a new ConsoleTable
    /// \param style The design of the console table
    /// \param padding Additional space between the text and the cell border
    explicit ConsoleTable(TableStyle style, unsigned int padding);
 
    /// Add a new column to the ConsoleTable
    /// \param name The name of the column
    void addColumn(std::string name);
 
    /// Add a new row with information into the ConsoleTable
    /// \param item The ConsoleTableRow which should be added
    void addRow(ConsoleTableRow item);
 
    /// Remove a row from the ConsoleTable at the given index
    /// \param index The index of the row which should be removed
    /// \return True if row was removed successfully, otherwise false
    bool removeRow(int index);

    /// Update the information in specific cell of a row
    /// \param data The new data that should be set
    /// \param row The index of the row which should be updated
    /// \param col The index of the column that should be updated
    /// \return True if the update was successful, otherwise false
    bool editRow(std::string data, int row, int col);

    /// Displays the table with columns and all content
    void printTable();

private:

    /// Additional space between cell border and cell text
    unsigned int padding = 1;

    /// Vector of all columns of the ConsoleTable
    Columns columns;
 
    /// Vector of all rows in the ConsoleTable
    Rows rows;

    // Table Style variables
    std::string style_line_horizontal;
    std::string style_line_vertical;
    std::string style_line_cross;
    std::string style_t_intersect_right;
    std::string style_t_intersect_left;
    std::string style_t_intersect_top;
    std::string style_t_intersect_bottom;
    std::string style_edge_top_left;
    std::string style_edge_top_right;
    std::string style_edge_bottom_left;
    std::string style_edge_bottom_right;

    /// Prints the horizontal seperator lines for the table
    /// \param maxWidths A vector that holds the maximum of all items in each column
    /// \param separator Defines what kind of seperator is used (Top, Middle, Bottom)
    /// \param invisibleRowLines If true seperator lines are only used between column headers and the first row, otherwise between every row
    void printSeparator(const std::vector<int> &maxWidths, Separator separator,
                        bool invisibleRowLines) const;

    /// Sets the design for the ConsoleTable
    /// \param style The style of the ConsoleTable (BASIC, LINED, DOUBLELINED)
    void setTableStyle(TableStyle style);

};


#endif //CONSOLETABLE_CONSOLETABLE_H
#include "ConsoleTable.h"


ConsoleTable::ConsoleTable(TableStyle style, unsigned int padding) {
    setTableStyle(style);
    this->padding = padding;
}

void ConsoleTable::addColumn(std::string name) {
    columns.push_back(name);
}

void ConsoleTable::printTable() {

    // Calculate column maxima
    std::vector<int> maxWidths(columns.size());
    for (auto &entry : rows) {
        for (int col = 0; col < columns.size(); col++) {
            std::string cellText = entry.getEntry().at(col);
            if (columns.at(col).length() > maxWidths.at(col))
                maxWidths.at(col) = columns.at(col).length();
            if (maxWidths.at(col) < cellText.length()) {
                maxWidths.at(col) = cellText.length();
            }
        }
    }

    printSeparator(maxWidths, Separator::TOP, false);

    // Print column values
    for (int col = 0; col < columns.size(); col++) {
        std::string cellText = columns.at(col);
        int len = cellText.length();
        std::string paddedText = cellText + std::string(maxWidths.at(col) - len, ' ');
        std::cout << style_line_vertical << std::string(padding, ' ') << paddedText
                  << std::string(padding, ' ');
        std::cout << (col == columns.size() - 1 ? style_line_vertical + "\n" : "");
    }

    printSeparator(maxWidths, Separator::MIDDLE, false);

    // Print cell values
    for (int row = 0; row < rows.size(); row++) {
        for (int col = 0; col < columns.size(); col++) {
            std::string cellText = rows.at(row).getEntry().at(col);
            std::string paddedText = cellText + std::string(maxWidths.at(col) - cellText.length(), ' ');
            std::cout << style_line_vertical << std::string(padding, ' ') << paddedText
                      << std::string(padding, ' ');
        }
        std::cout << style_line_vertical << std::endl;
        if (row == rows.size() - 1)
            printSeparator(maxWidths, Separator::BOTTOM, false);
        else
            printSeparator(maxWidths, Separator::MIDDLE, true);
    }
}

void ConsoleTable::printSeparator(const std::vector<int> &maxWidths, Separator separator,
                                  bool invisibleRowLines) const {
    for (int col = 0; col < columns.size(); ++col) {

        switch (separator) {
            case Separator::TOP:{
                std::cout << (col == 0 ? style_edge_top_left : "");
                break;
            }
            case Separator::MIDDLE:{
                if (invisibleRowLines)
                    continue;
                std::cout << (col == 0 ? style_t_intersect_left : "");
                break;
            }
            case Separator::BOTTOM:{
                std::cout << (col == 0 ? style_edge_bottom_left : "");
                break;
            }
        }

        std::cout << ConsoleTableUtils::repeatString(style_line_horizontal, padding);
        std::cout << ConsoleTableUtils::repeatString(style_line_horizontal, maxWidths.at(col));
        std::cout << ConsoleTableUtils::repeatString(style_line_horizontal, padding);
 
        switch (separator) {
            case Separator::TOP: {
                std::cout << (col != columns.size() - 1 ? style_t_intersect_top : style_edge_top_right);
                break;
            }
            case Separator::MIDDLE: {
                std::cout << (col != columns.size() - 1 ? style_line_cross : style_t_intersect_right);
                break;
            }
            case Separator::BOTTOM: {
                std::cout << (col != columns.size() - 1 ? style_t_intersect_bottom : style_edge_bottom_right);
                break;
            }
        }

        std::cout << (col == columns.size() - 1 ? "\n" : "");

    }
}

void ConsoleTable::addRow(ConsoleTableRow item) {
    rows.push_back(item);
}

bool ConsoleTable::removeRow(int index) {
    if (index > rows.size())
        return false;
    rows.erase(rows.begin() + index);
    return true;
}

bool ConsoleTable::editRow(std::string data, int row, int col) {
    if (row > rows.size())
        return false;

    if (col > columns.size())
        return false;

    auto entry = rows.at(row);
    entry.editEntry(data, col);
    return true;
}

void ConsoleTable::setTableStyle(TableStyle style) {
    switch (style) {
        case TableStyle::BASIC: {
            style_line_horizontal = "-";
            style_line_vertical = "|";
            style_line_cross = "+";

            style_t_intersect_right = "+";
            style_t_intersect_left = "+";
            style_t_intersect_top = "+";
            style_t_intersect_bottom = "+";

            style_edge_top_left = "+";
            style_edge_top_right = "+";
            style_edge_bottom_left = "+";
            style_edge_bottom_right = "+";
            break;
        }
        case TableStyle::LINED: {
            style_line_horizontal = "━";
            style_line_vertical = "┃";
            style_line_cross = "╋";

            style_t_intersect_right = "┫";
            style_t_intersect_left = "┣";
            style_t_intersect_top = "┳";
            style_t_intersect_bottom = "┻";

            style_edge_top_left = "┏";
            style_edge_top_right = "┓";
            style_edge_bottom_left = "┗";
            style_edge_bottom_right = "┛";
            break;
        }
        case TableStyle::DOUBLE_LINE: {
            style_line_horizontal = "═";
            style_line_vertical = "║";
            style_line_cross = "╬";

            style_t_intersect_right = "╣";
            style_t_intersect_left = "╠";
            style_t_intersect_top = "╦";
            style_t_intersect_bottom = "╩";

            style_edge_top_left = "╔";
            style_edge_top_right = "╗";
            style_edge_bottom_left = "╚";
            style_edge_bottom_right = "╝";
            break;
        }
    }
}
#ifndef CONSOLETABLE_CONSOLETABLEROW_H
#define CONSOLETABLE_CONSOLETABLEROW_H

#include <string>
#include <vector>

class ConsoleTableRow {
public:
 
    /// Create a new ConsoleTableRow
    /// \param width How many cells does the row have
    explicit ConsoleTableRow(int width);
 
    /// Add a new cell to the ConsoleTableRow
    /// \param data The data of the new cell
    /// \param column The column index of the new cell
    void addEntry(std::string data, int column);

    /// Updates a cell in the ConsoleTableRow with new data
    /// \param data The new data that should be updated
    /// \param column The index of the column that should be updated
    void editEntry(std::string data, int column);

    /// Returns the ConsoleTableRow
    /// \return The vector which holds all entries of the ConsoleTableRow
    std::vector <std::string> getEntry() const&;

private:

    /// The vector which holds all entries of the ConsoleTableRow
    std::vector <std::string> row;
 
};


#endif //CONSOLETABLE_CONSOLETABLEROW_H
#include "ConsoleTableRow.h"

ConsoleTableRow::ConsoleTableRow(int width) {
    row.resize(width);
}

void ConsoleTableRow::addEntry(std::string data, int column) {
    row.at(column) = data;
}

std::vector<std::string> ConsoleTableRow::getEntry() const&{
    return row;
}

void ConsoleTableRow::editEntry(std::string data, int column) {
    row.at(column) = data;
}
#ifndef CONSOLETABLE_CONSOLETABLEUTILS_H
#define CONSOLETABLE_CONSOLETABLEUTILS_H

#include <string>
#include <sstream>

class ConsoleTableUtils {
public:

    /// Repeats a given string n times
    /// \param input The string which should be repeated
    /// \param n How many times should the given string be repeated
    /// \return The repeated string
    static std::string repeatString(const std::string &input, int n){
        std::ostringstream os;
        for (int i = 0; i < n; i++)
            os << input;
        return os.str();
    }

};

#endif //CONSOLETABLE_CONSOLETABLEUTILS_H
#include <iostream>
#include <unistd.h>
#include "ConsoleTable.h"

int main() {
    ConsoleTable ct(TableStyle::BASIC, 2);
 
    ct.addColumn("Country");
    ct.addColumn("Capital");
    ct.addColumn("Population");
    ct.addColumn("Area");
    ct.addColumn("Currency");

    ConsoleTableRow row1(5);
    row1.addEntry("Germany", 0);
    row1.addEntry("Berlin", 1);
    row1.addEntry("82,800,000", 2);
    row1.addEntry("357,168 km2", 3);
    row1.addEntry("Euro", 4);
    ct.addRow(row1);

     ConsoleTableRow row2(5);
    row2.addEntry("Australia", 0);
    row2.addEntry("Canberra", 1);
    row2.addEntry("24,877,800", 2);
    row2.addEntry("7,692,024 km2", 3);
    row2.addEntry("Australian Dollar", 4);
    ct.addRow(row2);

    ConsoleTableRow row3(5);
    row3.addEntry("China", 0);
    row3.addEntry("Beijing", 1);
    row3.addEntry("1,403,500,365", 2);
    row3.addEntry("9,596,961 km2", 3);
    row3.addEntry("Yuan", 4);
    ct.addRow(row3);

    ConsoleTableRow row4(5);
    row4.addEntry("Iceland", 0);
    row4.addEntry("Reykjavik", 1);
    row4.addEntry("348,580", 2);
    row4.addEntry("102,775 km2", 3);
    row4.addEntry("Icelandic Krona", 4);
    ct.addRow(row4);

    // Print all rows
    ct.printTable();

    sleep(1);

    // Remove entry
    ct.removeRow(1);
    ct.printTable();

    sleep(1);

    // Update entry
    ct.editRow("New Country!",0, 1);
    ct.printTable();

    return 0;
}   

enter image description here enter image description here

#ifndef CONSOLETABLE_CONSOLETABLE_H
#define CONSOLETABLE_CONSOLETABLE_H

#include <string>
#include <vector>
#include <iostream>
#include "ConsoleTableRow.h"
#include "ConsoleTableUtils.h"
#include <sstream>

enum TableStyle {
    BASIC,
    LINED,
    DOUBLE_LINE,
};

enum HorizontalSeperator{
    SEPERATOR_TOP,
    SEPERATOR_MIDDLE,
    SEPERATOR_BOTTOM
};

class ConsoleTable {
public:

    ConsoleTable(TableStyle style);

    void setPadding(unsigned int width);

    void addColumn(std::string name);

    void addRow(ConsoleTableRow *item);

    bool removeRow(int index);

    bool editRow(std::string data, int row, int col);

    void printTable();

private:

    unsigned int padding = 1;

    std::vector<std::string> columns;
    std::vector<ConsoleTableRow *> entries;
    ConsoleTableUtils* utils;

    // Table Style variables
    std::string style_line_horizontal;
    std::string style_line_vertical;
    std::string style_line_cross;
    std::string style_t_intersect_right;
    std::string style_t_intersect_left;
    std::string style_t_intersect_top;
    std::string style_t_intersect_bottom;
    std::string style_edge_topleft;
    std::string style_edge_topright;
    std::string style_edge_buttomleft;
    std::string style_edge_buttomright;

    void printHorizontalSeperator(const std::vector<int> &maxWidths, HorizontalSeperator seperator) const;

    void setTableStyle(TableStyle style);

};


#endif //CONSOLETABLE_CONSOLETABLE_H
#include "ConsoleTable.h"


ConsoleTable::ConsoleTable(TableStyle style) {
    setTableStyle(style);
    this->utils = new ConsoleTableUtils();
}

void ConsoleTable::addColumn(std::string name) {
    this->columns.push_back(name);
}

void ConsoleTable::printTable() {

    // Calculate column maxima
    std::vector<int> maxWidths(this->columns.size());
    for (int row = 0; row < this->entries.size(); row++) {
        for (int col = 0; col < this->columns.size(); col++) {
            std::string cellText = this->entries[row]->getEntry()[col];
            if (this->columns[col].length() > maxWidths[col])
                maxWidths[col] = this->columns[col].length();
            if (maxWidths[col] < cellText.length()) {
                maxWidths[col] = cellText.length();
            }
        }
    }

    printHorizontalSeperator(maxWidths, SEPERATOR_TOP);

    // Print column values
    for (int col = 0; col < this->columns.size(); col++) {
        std::string cellText = this->columns[col];
        int len = cellText.length();
        std::string paddedText = cellText + std::string(maxWidths[col] - len, ' ');
        std::cout << this->style_line_vertical << std::string(this->padding, ' ') << paddedText
                  << std::string(this->padding, ' ');
        std::cout << (col == this->columns.size() - 1 ? this->style_line_vertical + "\n" : "");
    }

    printHorizontalSeperator(maxWidths, SEPERATOR_MIDDLE);

    // Print cell values
    for (int row = 0; row < this->entries.size(); row++) {
        for (int col = 0; col < this->columns.size(); col++) {
            std::string cellText = this->entries[row]->getEntry()[col];
            std::string paddedText = cellText + std::string(maxWidths[col] - cellText.length(), ' ');
            std::cout << this->style_line_vertical << std::string(this->padding, ' ') << paddedText
                      << std::string(this->padding, ' ');
        }
        std::cout << this->style_line_vertical << std::endl;
        if (row == this->entries.size() - 1)
            printHorizontalSeperator(maxWidths, SEPERATOR_BOTTOM);
        else
            printHorizontalSeperator(maxWidths, SEPERATOR_MIDDLE);
    }
}

void ConsoleTable::printHorizontalSeperator(const std::vector<int> &maxWidths, HorizontalSeperator seperator) const {
    for (int col = 0; col < columns.size(); ++col) {

        switch (seperator) {
            case SEPERATOR_TOP: {
                std::cout << (col == 0 ? this->style_edge_topleft : "");
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << utils->repeatString(this->style_line_horizontal, maxWidths[col]);
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << (col != columns.size() - 1 ? this->style_t_intersect_top : this->style_edge_topright);
                std::cout << (col == columns.size() - 1 ? "\n" : "");
                break;
            }
            case SEPERATOR_MIDDLE: {
                std::cout << (col == 0 ? this->style_t_intersect_left : "");
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << utils->repeatString(this->style_line_horizontal, maxWidths[col]);
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << (col != columns.size() - 1 ? this->style_line_cross : this->style_t_intersect_right);
                std::cout << (col == columns.size() - 1 ? "\n" : "");
                break;
            }
            case SEPERATOR_BOTTOM: {
                std::cout << (col == 0 ? this->style_edge_buttomleft : "");
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << utils->repeatString(this->style_line_horizontal, maxWidths[col]);
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout
                        << (col != columns.size() - 1 ? this->style_t_intersect_bottom : this->style_edge_buttomright);
                std::cout << (col == columns.size() - 1 ? "\n" : "");
                break;
            }
        }
    }
}

void ConsoleTable::addRow(ConsoleTableRow *item) {
    this->entries.push_back(item);
}

bool ConsoleTable::removeRow(int index) {
    if (index > this->entries.size())
        return false;
    this->entries.erase(this->entries.begin() + index);
    return true;
}

bool ConsoleTable::editRow(std::string data, int row, int col) {
    if(row > this->entries.size())
        return false;

    if(col > this->columns.size())
        return false;

    auto entry = this->entries[row];
    entry->editEntry(data, col);
    return true;
}

void ConsoleTable::setPadding(unsigned int width) {
    this->padding = width;
}

void ConsoleTable::setTableStyle(TableStyle style) {
    switch (style) {
        case BASIC: {
            this->style_line_horizontal = "-";
            this->style_line_vertical = "|";
            this->style_line_cross = "+";

            this->style_t_intersect_right = "+";
            this->style_t_intersect_left = "+";
            this->style_t_intersect_top = "+";
            this->style_t_intersect_bottom = "+";

            this->style_edge_topleft = "+";
            this->style_edge_topright = "+";
            this->style_edge_buttomleft = "+";
            this->style_edge_buttomright = "+";
            break;
        }
        case LINED: {
            this->style_line_horizontal = "━";
            this->style_line_vertical = "┃";
            this->style_line_cross = "╋";

            this->style_t_intersect_right = "┫";
            this->style_t_intersect_left = "┣";
            this->style_t_intersect_top = "┳";
            this->style_t_intersect_bottom = "┻";

            this->style_edge_topleft = "┏";
            this->style_edge_topright = "┓";
            this->style_edge_buttomleft = "┗";
            this->style_edge_buttomright = "┛";
            break;
        }
        case DOUBLE_LINE: {
            this->style_line_horizontal = "═";
            this->style_line_vertical = "║";
            this->style_line_cross = "╬";

            this->style_t_intersect_right = "╣";
            this->style_t_intersect_left = "╠";
            this->style_t_intersect_top = "╦";
            this->style_t_intersect_bottom = "╩";

            this->style_edge_topleft = "╔";
            this->style_edge_topright = "╗";
            this->style_edge_buttomleft = "╚";
            this->style_edge_buttomright = "╝";
            break;
        }
    }
}
#ifndef CONSOLETABLE_CONSOLETABLEENTRY_H
#define CONSOLETABLE_CONSOLETABLEENTRY_H

#include <string>
#include <vector>

class ConsoleTableRow {
public:

    ConsoleTableRow(int width);

    void addEntry(std::string data, int column);

    void editEntry(std::string data, int column);

    std::vector <std::string> getEntry();

private:
    std::vector <std::string> row;
};


#endif //CONSOLETABLE_CONSOLETABLEENTRY_H
#include "ConsoleTableRow.h"

ConsoleTableRow::ConsoleTableRow(int width) {
    this->row.resize(width);
}

void ConsoleTableRow::addEntry(std::string data, int column) {
    row[column] = data;
}

std::vector<std::string> ConsoleTableRow::getEntry() {
    return this->row;
}

void ConsoleTableRow::editEntry(std::string data, int column) {
    this->row[column] = data;
}
#ifndef CONSOLETABLE_CONSOLETABLEUTILS_H
#define CONSOLETABLE_CONSOLETABLEUTILS_H

#include <string>
#include <sstream>

class ConsoleTableUtils {
public:

    std::string repeatString(std::string input, int n) const;

}; 


#endif //CONSOLETABLE_CONSOLETABLEUTILS_H

##ConsoleTableUtils.cpp

#include "ConsoleTableUtils.h"

std::string ConsoleTableUtils::repeatString(std::string input, int n) const {
    std::ostringstream os;
    for (int i = 0; i < n; i++)
        os << input;
    return os.str();
}
#include <iostream>
#include <unistd.h>
#include "ConsoleTable.h"

int main() { 

    ConsoleTable ct(BASIC);
    ct.setPadding(1); 

    ct.addColumn("Country");
    ct.addColumn("Name");
    ct.addColumn("Profession");
    ct.addColumn("Age");

    auto entry = new ConsoleTableRow(4);
    entry->addEntry("Germany", 0);
    entry->addEntry("Michael", 1);
    entry->addEntry("Computer Engineer", 2);
    entry->addEntry("19", 3);
    ct.addRow(entry);

    auto entry2 = new ConsoleTableRow(4);
    entry2->addEntry("England", 0);
    entry2->addEntry("Robert", 1);
    entry2->addEntry("Artist", 2);
    entry2->addEntry("34", 3);
    ct.addRow(entry2); 

    auto entry3 = new ConsoleTableRow(4);
    entry3->addEntry("United Kingdom", 0);
    entry3->addEntry("Julia", 1);
    entry3->addEntry("Designer", 2);
    entry3->addEntry("42", 3);
    ct.addRow(entry3); 

    auto entry4 = new ConsoleTableRow(4);
    entry4->addEntry("United Staates", 0);
    entry4->addEntry("Jo", 1);
    entry4->addEntry("Actor", 2);
    entry4->addEntry("21", 3);
    ct.addRow(entry4);

    // Print all entries
    ct.printTable();

    return 0;
}
Re-factored code, applied most mentioned suggestions
Source Link
766F6964
  • 901
  • 1
  • 6
  • 22

enter image description here enter image description hereenter image description here

#ifndef CONSOLETABLE_CONSOLETABLE_H
#define CONSOLETABLE_CONSOLETABLE_H

#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <memory>
#include "ConsoleTableRow.h"
#include "ConsoleTableUtils.h"
#include <sstream>

enum class TableStyle {
    BASIC,
    LINED,
    DOUBLE_LINE,
};

enum HorizontalSeperatorclass Separator {
    SEPERATOR_TOPTOP,
    SEPERATOR_MIDDLEMIDDLE,
    SEPERATOR_BOTTOMBOTTOM
}; 

typedef std::vector<std::string> Columns;
typedef std::vector<ConsoleTableRow> Rows;


class ConsoleTable {
public:

    /// Create a new ConsoleTable(TableStyle
    /// \param style); The design of the console table
    /// \param padding Additional space between the text and the cell border
    voidexplicit setPaddingConsoleTable(TableStyle style, unsigned int widthpadding); 

    /// Add a new column to the ConsoleTable
    /// \param name The name of the column
    void addColumn(std::string name); 

    /// Add a new row with information into the ConsoleTable
    /// \param item The ConsoleTableRow which should be added
    void addRow(ConsoleTableRow *itemitem); 

    /// Remove a row from the ConsoleTable at the given index
    /// \param index The index of the row which should be removed
    /// \return True if row was removed successfully, otherwise false
    bool removeRow(int index);

    /// Update the information in specific cell of a row
    /// \param data The new data that should be set
    /// \param row The index of the row which should be updated
    /// \param col The index of the column that should be updated
    /// \return True if the update was successful, otherwise false
    bool editRow(std::string data, int row, int col);

    /// Displays the table with columns and all content
    void printTable();

private:

    /// Additional space between cell border and cell text
    unsigned int padding = 1;

    std::vector<std::string>/// Vector of all columns of the ConsoleTable
    Columns columns; 

    std::vector<ConsoleTableRow/// *>Vector entries;of all rows in the ConsoleTable
    ConsoleTableUtils*Rows utils;rows;

    // Table Style variables
    std::string style_line_horizontal;
    std::string style_line_vertical;
    std::string style_line_cross;
    std::string style_t_intersect_right;
    std::string style_t_intersect_left;
    std::string style_t_intersect_top;
    std::string style_t_intersect_bottom;
    std::string style_edge_topleft;style_edge_top_left;
    std::string style_edge_topright;style_edge_top_right;
    std::string style_edge_buttomleft;style_edge_bottom_left;
    std::string style_edge_buttomright;style_edge_bottom_right;

    /// Prints the horizontal seperator lines for the table
    /// \param maxWidths A vector that holds the maximum of all items in each column
    /// \param separator Defines what kind of seperator is used (Top, Middle, Bottom)
    /// \param invisibleRowLines If true seperator lines are only used between column headers and the first row, otherwise between every row
    void printHorizontalSeperatorprintSeparator(const std::vector<int> &maxWidths, HorizontalSeperatorSeparator seperatorseparator,
                        bool invisibleRowLines) const;

    /// Sets the design for the ConsoleTable
    /// \param style The style of the ConsoleTable (BASIC, LINED, DOUBLELINED)
    void setTableStyle(TableStyle style);

};


#endif //CONSOLETABLE_CONSOLETABLE_H
#include "ConsoleTable.h"


ConsoleTable::ConsoleTable(TableStyle style, unsigned int padding) {
    setTableStyle(style);
    this->utils>padding = new ConsoleTableUtils();padding;
}

void ConsoleTable::addColumn(std::string name) {
    this->columnscolumns.push_back(name);
}

void ConsoleTable::printTable() {

    // Calculate column maxima
    std::vector<int> maxWidths(this->columnscolumns.size());
    for (int row = 0; rowauto <&entry this->entries.size();: row++rows) {
        for (int col = 0; col < this->columnscolumns.size(); col++) {
            std::string cellText = this->entries[row]->getEntryentry.getEntry()[col];.at(col);
            if (this->columns[col]columns.at(col).length() > maxWidths[col]maxWidths.at(col))
                maxWidths[col]maxWidths.at(col) = this->columns[col]columns.at(col).length();
            if (maxWidths[col]maxWidths.at(col) < cellText.length()) {
                maxWidths[col]maxWidths.at(col) = cellText.length();
            }
        }
    }

    printHorizontalSeperatorprintSeparator(maxWidths, SEPERATOR_TOPSeparator::TOP, false);

    // Print column values
    for (int col = 0; col < this->columnscolumns.size(); col++) {
        std::string cellText = this->columns[col];columns.at(col);
        int len = cellText.length();
        std::string paddedText = cellText + std::string(maxWidths[col]maxWidths.at(col) - len, ' ');
        std::cout << this->style_line_verticalstyle_line_vertical << std::string(this->paddingpadding, ' ') << paddedText
                  << std::string(this->paddingpadding, ' ');
        std::cout << (col == this->columnscolumns.size() - 1 ? this->style_line_verticalstyle_line_vertical + "\n" : "");
    }

    printHorizontalSeperatorprintSeparator(maxWidths, SEPERATOR_MIDDLESeparator::MIDDLE, false);

    // Print cell values
    for (int row = 0; row < this->entriesrows.size(); row++) {
        for (int col = 0; col < this->columnscolumns.size(); col++) {
            std::string cellText = this->entries[row]->getEntryrows.at(row)[col];.getEntry().at(col);
            std::string paddedText = cellText + std::string(maxWidths[col]maxWidths.at(col) - cellText.length(), ' ');
            std::cout << this->style_line_verticalstyle_line_vertical << std::string(this->paddingpadding, ' ') << paddedText
                      << std::string(this->paddingpadding, ' ');
        }
        std::cout << this->style_line_verticalstyle_line_vertical << std::endl;
        if (row == this->entriesrows.size() - 1)
            printHorizontalSeperatorprintSeparator(maxWidths, SEPERATOR_BOTTOMSeparator::BOTTOM, false);
        else
            printHorizontalSeperatorprintSeparator(maxWidths, SEPERATOR_MIDDLESeparator::MIDDLE, true);
    }
}

void ConsoleTable::printHorizontalSeperatorprintSeparator(const std::vector<int> &maxWidths, HorizontalSeperatorSeparator seperatorseparator,
                                  bool invisibleRowLines) const {
    for (int col = 0; col < columns.size(); ++col) {

        switch (seperatorseparator) {
            case SEPERATOR_TOP: {
                std::cout << (col == 0 ? this->style_edge_topleft : "");
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << utils->repeatString(this->style_line_horizontal, maxWidths[col]);
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                stdSeparator::cout << (col != columns.size() - 1 ? this->style_t_intersect_top TOP: this->style_edge_topright);{
                std::cout << (col == columns.size() - 10 ? "\n"style_edge_top_left : "");
                break;
            }
            case SEPERATOR_MIDDLE: {
                std::cout << (col == 0 ? this->style_t_intersect_left : "");
                stdSeparator::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std:MIDDLE:cout << utils->repeatString(this->style_line_horizontal, maxWidths[col]);{
                std::cout <<if utils->repeatString(this->style_line_horizontal, this->paddinginvisibleRowLines);
                std::cout << (col != columns.size() - 1 ? this->style_line_cross : this->style_t_intersect_right);continue;
                std::cout << (col == columns.size() - 10 ? "\n"style_t_intersect_left : "");
                break;
            }
            case SEPERATOR_BOTTOM: {
                std::cout << (col == 0 ? this->style_edge_buttomleft : "");
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << utils->repeatString(this->style_line_horizontal, maxWidths[col]);
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                stdSeparator::cout
                        << (col != columns.size() - 1 ? this->style_t_intersect_bottom BOTTOM: this->style_edge_buttomright);{
                std::cout << (col == columns.size() - 10 ? "\n"style_edge_bottom_left : "");
                break;
            }
        }

        std::cout << ConsoleTableUtils::repeatString(style_line_horizontal, padding);
        std::cout << ConsoleTableUtils::repeatString(style_line_horizontal, maxWidths.at(col));
        std::cout << ConsoleTableUtils::repeatString(style_line_horizontal, padding);

        switch (separator) {
            case Separator::TOP: {
                std::cout << (col != columns.size() - 1 ? style_t_intersect_top : style_edge_top_right);
                break;
            }
            case Separator::MIDDLE: {
                std::cout << (col != columns.size() - 1 ? style_line_cross : style_t_intersect_right);
                break;
            }
            case Separator::BOTTOM: {
                std::cout << (col != columns.size() - 1 ? style_t_intersect_bottom : style_edge_bottom_right);
                break;
            }
        }

        std::cout << (col == columns.size() - 1 ? "\n" : "");

    }
}

void ConsoleTable::addRow(ConsoleTableRow *itemitem) {
    this->entriesrows.push_back(item);
}

bool ConsoleTable::removeRow(int index) {
    if (index > this->entriesrows.size())
        return false;
    this->entriesrows.erase(this->entriesrows.begin() + index);
    return true;
}

bool ConsoleTable::editRow(std::string data, int row, int col) {
    if (row > this->entriesrows.size())
        return false;

    if (col > this->columnscolumns.size())
        return false;

    auto entry = this->entries[row];rows.at(row);
    entry->editEntry.editEntry(data, col);
    return true;
}

void ConsoleTable::setPadding(unsigned int width) {
    this->padding = width;
}

void ConsoleTable::setTableStyle(TableStyle style) {
    switch (style) {
        case TableStyle::BASIC: {
            this->style_line_horizontalstyle_line_horizontal = "-";
            this->style_line_verticalstyle_line_vertical = "|";
            this->style_line_crossstyle_line_cross = "+";

            this->style_t_intersect_rightstyle_t_intersect_right = "+";
            this->style_t_intersect_leftstyle_t_intersect_left = "+";
            this->style_t_intersect_topstyle_t_intersect_top = "+";
            this->style_t_intersect_bottomstyle_t_intersect_bottom = "+";

            this->style_edge_topleftstyle_edge_top_left = "+";
            this->style_edge_toprightstyle_edge_top_right = "+";
            this->style_edge_buttomleftstyle_edge_bottom_left = "+";
            this->style_edge_buttomrightstyle_edge_bottom_right = "+";
            break;
        }
        case TableStyle::LINED: {
            this->style_line_horizontalstyle_line_horizontal = "━";
            this->style_line_verticalstyle_line_vertical = "┃";
            this->style_line_crossstyle_line_cross = "╋";

            this->style_t_intersect_rightstyle_t_intersect_right = "┫";
            this->style_t_intersect_leftstyle_t_intersect_left = "┣";
            this->style_t_intersect_topstyle_t_intersect_top = "┳";
            this->style_t_intersect_bottomstyle_t_intersect_bottom = "┻";

            this->style_edge_topleftstyle_edge_top_left = "┏";
            this->style_edge_toprightstyle_edge_top_right = "┓";
            this->style_edge_buttomleftstyle_edge_bottom_left = "┗";
            this->style_edge_buttomrightstyle_edge_bottom_right = "┛";
            break;
        }
        case TableStyle::DOUBLE_LINE: {
            this->style_line_horizontalstyle_line_horizontal = "═";
            this->style_line_verticalstyle_line_vertical = "║";
            this->style_line_crossstyle_line_cross = "╬";

            this->style_t_intersect_rightstyle_t_intersect_right = "╣";
            this->style_t_intersect_leftstyle_t_intersect_left = "╠";
            this->style_t_intersect_topstyle_t_intersect_top = "╦";
            this->style_t_intersect_bottomstyle_t_intersect_bottom = "╩";

            this->style_edge_topleftstyle_edge_top_left = "╔";
            this->style_edge_toprightstyle_edge_top_right = "╗";
            this->style_edge_buttomleftstyle_edge_bottom_left = "╚";
            this->style_edge_buttomrightstyle_edge_bottom_right = "╝";
            break;
        }
    }
}
#ifndef CONSOLETABLE_CONSOLETABLEENTRY_HCONSOLETABLE_CONSOLETABLEROW_H
#define CONSOLETABLE_CONSOLETABLEENTRY_HCONSOLETABLE_CONSOLETABLEROW_H

#include <string>
#include <vector>

class ConsoleTableRow {
public: 

    /// Create a new ConsoleTableRow
    /// \param width How many cells does the row have
    explicit ConsoleTableRow(int width); 

    /// Add a new cell to the ConsoleTableRow
    /// \param data The data of the new cell
    /// \param column The column index of the new cell
    void addEntry(std::string data, int column);

    /// Updates a cell in the ConsoleTableRow with new data
    /// \param data The new data that should be updated
    /// \param column The index of the column that should be updated
    void editEntry(std::string data, int column);

    /// Returns the ConsoleTableRow
    /// \return The vector which holds all entries of the ConsoleTableRow
    std::vector <std::string> getEntry(); const&;

private:

    /// The vector which holds all entries of the ConsoleTableRow
    std::vector <std::string> row; 

};


#endif //CONSOLETABLE_CONSOLETABLEENTRY_HCONSOLETABLE_CONSOLETABLEROW_H
#include "ConsoleTableRow.h"

ConsoleTableRow::ConsoleTableRow(int width) {
    this->rowrow.resize(width);
}

void ConsoleTableRow::addEntry(std::string data, int column) {
    row[column]row.at(column) = data;
}

std::vector<std::string> ConsoleTableRow::getEntry() const&{
    return this->row;row;
}

void ConsoleTableRow::editEntry(std::string data, int column) {
    this->row[column]row.at(column) = data;
}
#ifndef CONSOLETABLE_CONSOLETABLEUTILS_H
#define CONSOLETABLE_CONSOLETABLEUTILS_H

#include <string>
#include <sstream>

class ConsoleTableUtils {
public:

    std::string/// repeatString(std::stringRepeats input,a intgiven string n) const;

};

times
#endif    //CONSOLETABLE_CONSOLETABLEUTILS_H/ \param input The string which should be repeated

##ConsoleTableUtils.cpp

#include "ConsoleTableUtils.h"   /// \param n How many times should the given string be repeated
    /// \return The repeated string
    static std::string ConsoleTableUtils::repeatString(const std::string input&input, int n) const {
        std::ostringstream os;
        for (int i = 0; i < n; i++)
            os << input;
        return os.str();
    }

};

#endif //CONSOLETABLE_CONSOLETABLEUTILS_H
#include <iostream>
#include <unistd.h>
#include "ConsoleTable.h"

int main() {
 
    ConsoleTable ct(TableStyle::BASIC, 2); 

    ct.setPaddingaddColumn(1"Country");
 
    ct.addColumn("Country""Capital");
    ct.addColumn("Name""Population");
    ct.addColumn("Profession""Area");
    ct.addColumn("Age""Currency");

    auto entry = new ConsoleTableRow row1(45);
    entry->addEntryrow1.addEntry("Germany", 0);
    entry->addEntryrow1.addEntry("Michael""Berlin", 1);
    entry->addEntryrow1.addEntry("Computer Engineer""82,800,000", 2);
    entry->addEntryrow1.addEntry("19""357,168 km2", 3);
    ctrow1.addRowaddEntry(entry"Euro", 4);
 
    autoct.addRow(row1);

 entry2 = new  ConsoleTableRow row2(45);
    entry2->addEntryrow2.addEntry("England""Australia", 0);
    entry2->addEntryrow2.addEntry("Robert""Canberra", 1);
    entry2->addEntryrow2.addEntry("Artist""24,877,800", 2);
    entry2->addEntryrow2.addEntry("34""7,692,024 km2", 3);
    ctrow2.addRowaddEntry(entry2"Australian Dollar", 4);
 
    autoct.addRow(row2);

 entry3 = new ConsoleTableRow row3(45);
    entry3->addEntryrow3.addEntry("United Kingdom""China", 0);
    entry3->addEntryrow3.addEntry("Julia""Beijing", 1);
    entry3->addEntryrow3.addEntry("Designer""1,403,500,365", 2);
    entry3->addEntryrow3.addEntry("42""9,596,961 km2", 3);
    ctrow3.addRowaddEntry(entry3"Yuan", 4);
 
    autoct.addRow(row3);

 entry4 = new ConsoleTableRow row4(45);
    entry4->addEntryrow4.addEntry("United Staates""Iceland", 0);
    entry4->addEntryrow4.addEntry("Jo""Reykjavik", 1);
    entry4->addEntryrow4.addEntry("Actor""348,580", 2);
    entry4->addEntryrow4.addEntry("21""102,775 km2", 3);
    row4.addEntry("Icelandic Krona", 4);
    ct.addRow(entry4row4);

    // Print all entriesrows
    ct.printTable();

    sleep(1);

    // Remove entry
    ct.removeRow(1);
    ct.printTable();

    sleep(1);

    // Update entry
    ct.editRow("New Country!",0, 1);
    ct.printTable();

    return 0;
}   

enter image description here enter image description here

#ifndef CONSOLETABLE_CONSOLETABLE_H
#define CONSOLETABLE_CONSOLETABLE_H

#include <string>
#include <vector>
#include <iostream>
#include "ConsoleTableRow.h"
#include "ConsoleTableUtils.h"
#include <sstream>

enum TableStyle {
    BASIC,
    LINED,
    DOUBLE_LINE,
};

enum HorizontalSeperator{
    SEPERATOR_TOP,
    SEPERATOR_MIDDLE,
    SEPERATOR_BOTTOM
};

class ConsoleTable {
public:

    ConsoleTable(TableStyle style);

    void setPadding(unsigned int width);

    void addColumn(std::string name);

    void addRow(ConsoleTableRow *item);

    bool removeRow(int index);

    bool editRow(std::string data, int row, int col);

    void printTable();

private:

    unsigned int padding = 1;

    std::vector<std::string> columns;
    std::vector<ConsoleTableRow *> entries;
    ConsoleTableUtils* utils;

    // Table Style variables
    std::string style_line_horizontal;
    std::string style_line_vertical;
    std::string style_line_cross;
    std::string style_t_intersect_right;
    std::string style_t_intersect_left;
    std::string style_t_intersect_top;
    std::string style_t_intersect_bottom;
    std::string style_edge_topleft;
    std::string style_edge_topright;
    std::string style_edge_buttomleft;
    std::string style_edge_buttomright;

    void printHorizontalSeperator(const std::vector<int> &maxWidths, HorizontalSeperator seperator) const;

    void setTableStyle(TableStyle style);

};


#endif //CONSOLETABLE_CONSOLETABLE_H
#include "ConsoleTable.h"


ConsoleTable::ConsoleTable(TableStyle style) {
    setTableStyle(style);
    this->utils = new ConsoleTableUtils();
}

void ConsoleTable::addColumn(std::string name) {
    this->columns.push_back(name);
}

void ConsoleTable::printTable() {

    // Calculate column maxima
    std::vector<int> maxWidths(this->columns.size());
    for (int row = 0; row < this->entries.size(); row++) {
        for (int col = 0; col < this->columns.size(); col++) {
            std::string cellText = this->entries[row]->getEntry()[col];
            if (this->columns[col].length() > maxWidths[col])
                maxWidths[col] = this->columns[col].length();
            if (maxWidths[col] < cellText.length()) {
                maxWidths[col] = cellText.length();
            }
        }
    }

    printHorizontalSeperator(maxWidths, SEPERATOR_TOP);

    // Print column values
    for (int col = 0; col < this->columns.size(); col++) {
        std::string cellText = this->columns[col];
        int len = cellText.length();
        std::string paddedText = cellText + std::string(maxWidths[col] - len, ' ');
        std::cout << this->style_line_vertical << std::string(this->padding, ' ') << paddedText
                  << std::string(this->padding, ' ');
        std::cout << (col == this->columns.size() - 1 ? this->style_line_vertical + "\n" : "");
    }

    printHorizontalSeperator(maxWidths, SEPERATOR_MIDDLE);

    // Print cell values
    for (int row = 0; row < this->entries.size(); row++) {
        for (int col = 0; col < this->columns.size(); col++) {
            std::string cellText = this->entries[row]->getEntry()[col];
            std::string paddedText = cellText + std::string(maxWidths[col] - cellText.length(), ' ');
            std::cout << this->style_line_vertical << std::string(this->padding, ' ') << paddedText
                      << std::string(this->padding, ' ');
        }
        std::cout << this->style_line_vertical << std::endl;
        if (row == this->entries.size() - 1)
            printHorizontalSeperator(maxWidths, SEPERATOR_BOTTOM);
        else
            printHorizontalSeperator(maxWidths, SEPERATOR_MIDDLE);
    }
}

void ConsoleTable::printHorizontalSeperator(const std::vector<int> &maxWidths, HorizontalSeperator seperator) const {
    for (int col = 0; col < columns.size(); ++col) {

        switch (seperator) {
            case SEPERATOR_TOP: {
                std::cout << (col == 0 ? this->style_edge_topleft : "");
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << utils->repeatString(this->style_line_horizontal, maxWidths[col]);
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << (col != columns.size() - 1 ? this->style_t_intersect_top : this->style_edge_topright);
                std::cout << (col == columns.size() - 1 ? "\n" : "");
                break;
            }
            case SEPERATOR_MIDDLE: {
                std::cout << (col == 0 ? this->style_t_intersect_left : "");
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << utils->repeatString(this->style_line_horizontal, maxWidths[col]);
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << (col != columns.size() - 1 ? this->style_line_cross : this->style_t_intersect_right);
                std::cout << (col == columns.size() - 1 ? "\n" : "");
                break;
            }
            case SEPERATOR_BOTTOM: {
                std::cout << (col == 0 ? this->style_edge_buttomleft : "");
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout << utils->repeatString(this->style_line_horizontal, maxWidths[col]);
                std::cout << utils->repeatString(this->style_line_horizontal, this->padding);
                std::cout
                        << (col != columns.size() - 1 ? this->style_t_intersect_bottom : this->style_edge_buttomright);
                std::cout << (col == columns.size() - 1 ? "\n" : "");
                break;
            }
        }
    }
}

void ConsoleTable::addRow(ConsoleTableRow *item) {
    this->entries.push_back(item);
}

bool ConsoleTable::removeRow(int index) {
    if (index > this->entries.size())
        return false;
    this->entries.erase(this->entries.begin() + index);
    return true;
}

bool ConsoleTable::editRow(std::string data, int row, int col) {
    if(row > this->entries.size())
        return false;

    if(col > this->columns.size())
        return false;

    auto entry = this->entries[row];
    entry->editEntry(data, col);
    return true;
}

void ConsoleTable::setPadding(unsigned int width) {
    this->padding = width;
}

void ConsoleTable::setTableStyle(TableStyle style) {
    switch (style) {
        case BASIC: {
            this->style_line_horizontal = "-";
            this->style_line_vertical = "|";
            this->style_line_cross = "+";

            this->style_t_intersect_right = "+";
            this->style_t_intersect_left = "+";
            this->style_t_intersect_top = "+";
            this->style_t_intersect_bottom = "+";

            this->style_edge_topleft = "+";
            this->style_edge_topright = "+";
            this->style_edge_buttomleft = "+";
            this->style_edge_buttomright = "+";
            break;
        }
        case LINED: {
            this->style_line_horizontal = "━";
            this->style_line_vertical = "┃";
            this->style_line_cross = "╋";

            this->style_t_intersect_right = "┫";
            this->style_t_intersect_left = "┣";
            this->style_t_intersect_top = "┳";
            this->style_t_intersect_bottom = "┻";

            this->style_edge_topleft = "┏";
            this->style_edge_topright = "┓";
            this->style_edge_buttomleft = "┗";
            this->style_edge_buttomright = "┛";
            break;
        }
        case DOUBLE_LINE: {
            this->style_line_horizontal = "═";
            this->style_line_vertical = "║";
            this->style_line_cross = "╬";

            this->style_t_intersect_right = "╣";
            this->style_t_intersect_left = "╠";
            this->style_t_intersect_top = "╦";
            this->style_t_intersect_bottom = "╩";

            this->style_edge_topleft = "╔";
            this->style_edge_topright = "╗";
            this->style_edge_buttomleft = "╚";
            this->style_edge_buttomright = "╝";
            break;
        }
    }
}
#ifndef CONSOLETABLE_CONSOLETABLEENTRY_H
#define CONSOLETABLE_CONSOLETABLEENTRY_H

#include <string>
#include <vector>

class ConsoleTableRow {
public:

    ConsoleTableRow(int width);

    void addEntry(std::string data, int column);

    void editEntry(std::string data, int column);

    std::vector <std::string> getEntry();

private:
    std::vector <std::string> row;
};


#endif //CONSOLETABLE_CONSOLETABLEENTRY_H
#include "ConsoleTableRow.h"

ConsoleTableRow::ConsoleTableRow(int width) {
    this->row.resize(width);
}

void ConsoleTableRow::addEntry(std::string data, int column) {
    row[column] = data;
}

std::vector<std::string> ConsoleTableRow::getEntry() {
    return this->row;
}

void ConsoleTableRow::editEntry(std::string data, int column) {
    this->row[column] = data;
}
#ifndef CONSOLETABLE_CONSOLETABLEUTILS_H
#define CONSOLETABLE_CONSOLETABLEUTILS_H

#include <string>
#include <sstream>

class ConsoleTableUtils {
public:

    std::string repeatString(std::string input, int n) const;

};


#endif //CONSOLETABLE_CONSOLETABLEUTILS_H

##ConsoleTableUtils.cpp

#include "ConsoleTableUtils.h"

std::string ConsoleTableUtils::repeatString(std::string input, int n) const {
    std::ostringstream os;
    for (int i = 0; i < n; i++)
        os << input;
    return os.str();
}
#include <iostream>
#include <unistd.h>
#include "ConsoleTable.h"

int main() {
 
    ConsoleTable ct(BASIC);
    ct.setPadding(1);
 
    ct.addColumn("Country");
    ct.addColumn("Name");
    ct.addColumn("Profession");
    ct.addColumn("Age");

    auto entry = new ConsoleTableRow(4);
    entry->addEntry("Germany", 0);
    entry->addEntry("Michael", 1);
    entry->addEntry("Computer Engineer", 2);
    entry->addEntry("19", 3);
    ct.addRow(entry);
 
    auto entry2 = new ConsoleTableRow(4);
    entry2->addEntry("England", 0);
    entry2->addEntry("Robert", 1);
    entry2->addEntry("Artist", 2);
    entry2->addEntry("34", 3);
    ct.addRow(entry2);
 
    auto entry3 = new ConsoleTableRow(4);
    entry3->addEntry("United Kingdom", 0);
    entry3->addEntry("Julia", 1);
    entry3->addEntry("Designer", 2);
    entry3->addEntry("42", 3);
    ct.addRow(entry3);
 
    auto entry4 = new ConsoleTableRow(4);
    entry4->addEntry("United Staates", 0);
    entry4->addEntry("Jo", 1);
    entry4->addEntry("Actor", 2);
    entry4->addEntry("21", 3);
    ct.addRow(entry4);

    // Print all entries
    ct.printTable();

    return 0;
}

enter image description here

#ifndef CONSOLETABLE_CONSOLETABLE_H
#define CONSOLETABLE_CONSOLETABLE_H

#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <memory>
#include "ConsoleTableRow.h"
#include "ConsoleTableUtils.h"


enum class TableStyle {
    BASIC,
    LINED,
    DOUBLE_LINE,
};

enum class Separator {
    TOP,
    MIDDLE,
    BOTTOM
}; 

typedef std::vector<std::string> Columns;
typedef std::vector<ConsoleTableRow> Rows;


class ConsoleTable {
public:

    /// Create a new ConsoleTable
    /// \param style The design of the console table
    /// \param padding Additional space between the text and the cell border
    explicit ConsoleTable(TableStyle style, unsigned int padding); 

    /// Add a new column to the ConsoleTable
    /// \param name The name of the column
    void addColumn(std::string name); 

    /// Add a new row with information into the ConsoleTable
    /// \param item The ConsoleTableRow which should be added
    void addRow(ConsoleTableRow item); 

    /// Remove a row from the ConsoleTable at the given index
    /// \param index The index of the row which should be removed
    /// \return True if row was removed successfully, otherwise false
    bool removeRow(int index);

    /// Update the information in specific cell of a row
    /// \param data The new data that should be set
    /// \param row The index of the row which should be updated
    /// \param col The index of the column that should be updated
    /// \return True if the update was successful, otherwise false
    bool editRow(std::string data, int row, int col);

    /// Displays the table with columns and all content
    void printTable();

private:

    /// Additional space between cell border and cell text
    unsigned int padding = 1;

    /// Vector of all columns of the ConsoleTable
    Columns columns; 

    /// Vector of all rows in the ConsoleTable
    Rows rows;

    // Table Style variables
    std::string style_line_horizontal;
    std::string style_line_vertical;
    std::string style_line_cross;
    std::string style_t_intersect_right;
    std::string style_t_intersect_left;
    std::string style_t_intersect_top;
    std::string style_t_intersect_bottom;
    std::string style_edge_top_left;
    std::string style_edge_top_right;
    std::string style_edge_bottom_left;
    std::string style_edge_bottom_right;

    /// Prints the horizontal seperator lines for the table
    /// \param maxWidths A vector that holds the maximum of all items in each column
    /// \param separator Defines what kind of seperator is used (Top, Middle, Bottom)
    /// \param invisibleRowLines If true seperator lines are only used between column headers and the first row, otherwise between every row
    void printSeparator(const std::vector<int> &maxWidths, Separator separator,
                        bool invisibleRowLines) const;

    /// Sets the design for the ConsoleTable
    /// \param style The style of the ConsoleTable (BASIC, LINED, DOUBLELINED)
    void setTableStyle(TableStyle style);

};


#endif //CONSOLETABLE_CONSOLETABLE_H
#include "ConsoleTable.h"


ConsoleTable::ConsoleTable(TableStyle style, unsigned int padding) {
    setTableStyle(style);
    this->padding = padding;
}

void ConsoleTable::addColumn(std::string name) {
    columns.push_back(name);
}

void ConsoleTable::printTable() {

    // Calculate column maxima
    std::vector<int> maxWidths(columns.size());
    for (auto &entry : rows) {
        for (int col = 0; col < columns.size(); col++) {
            std::string cellText = entry.getEntry().at(col);
            if (columns.at(col).length() > maxWidths.at(col))
                maxWidths.at(col) = columns.at(col).length();
            if (maxWidths.at(col) < cellText.length()) {
                maxWidths.at(col) = cellText.length();
            }
        }
    }

    printSeparator(maxWidths, Separator::TOP, false);

    // Print column values
    for (int col = 0; col < columns.size(); col++) {
        std::string cellText = columns.at(col);
        int len = cellText.length();
        std::string paddedText = cellText + std::string(maxWidths.at(col) - len, ' ');
        std::cout << style_line_vertical << std::string(padding, ' ') << paddedText
                  << std::string(padding, ' ');
        std::cout << (col == columns.size() - 1 ? style_line_vertical + "\n" : "");
    }

    printSeparator(maxWidths, Separator::MIDDLE, false);

    // Print cell values
    for (int row = 0; row < rows.size(); row++) {
        for (int col = 0; col < columns.size(); col++) {
            std::string cellText = rows.at(row).getEntry().at(col);
            std::string paddedText = cellText + std::string(maxWidths.at(col) - cellText.length(), ' ');
            std::cout << style_line_vertical << std::string(padding, ' ') << paddedText
                      << std::string(padding, ' ');
        }
        std::cout << style_line_vertical << std::endl;
        if (row == rows.size() - 1)
            printSeparator(maxWidths, Separator::BOTTOM, false);
        else
            printSeparator(maxWidths, Separator::MIDDLE, true);
    }
}

void ConsoleTable::printSeparator(const std::vector<int> &maxWidths, Separator separator,
                                  bool invisibleRowLines) const {
    for (int col = 0; col < columns.size(); ++col) {

        switch (separator) {
            case Separator::TOP:{
                std::cout << (col == 0 ? style_edge_top_left : "");
                break;
            }
            case Separator::MIDDLE:{
                if (invisibleRowLines)
                    continue;
                std::cout << (col == 0 ? style_t_intersect_left : "");
                break;
            }
            case Separator::BOTTOM:{
                std::cout << (col == 0 ? style_edge_bottom_left : "");
                break;
            }
        }

        std::cout << ConsoleTableUtils::repeatString(style_line_horizontal, padding);
        std::cout << ConsoleTableUtils::repeatString(style_line_horizontal, maxWidths.at(col));
        std::cout << ConsoleTableUtils::repeatString(style_line_horizontal, padding);

        switch (separator) {
            case Separator::TOP: {
                std::cout << (col != columns.size() - 1 ? style_t_intersect_top : style_edge_top_right);
                break;
            }
            case Separator::MIDDLE: {
                std::cout << (col != columns.size() - 1 ? style_line_cross : style_t_intersect_right);
                break;
            }
            case Separator::BOTTOM: {
                std::cout << (col != columns.size() - 1 ? style_t_intersect_bottom : style_edge_bottom_right);
                break;
            }
        }

        std::cout << (col == columns.size() - 1 ? "\n" : "");

    }
}

void ConsoleTable::addRow(ConsoleTableRow item) {
    rows.push_back(item);
}

bool ConsoleTable::removeRow(int index) {
    if (index > rows.size())
        return false;
    rows.erase(rows.begin() + index);
    return true;
}

bool ConsoleTable::editRow(std::string data, int row, int col) {
    if (row > rows.size())
        return false;

    if (col > columns.size())
        return false;

    auto entry = rows.at(row);
    entry.editEntry(data, col);
    return true;
}

void ConsoleTable::setTableStyle(TableStyle style) {
    switch (style) {
        case TableStyle::BASIC: {
            style_line_horizontal = "-";
            style_line_vertical = "|";
            style_line_cross = "+";

            style_t_intersect_right = "+";
            style_t_intersect_left = "+";
            style_t_intersect_top = "+";
            style_t_intersect_bottom = "+";

            style_edge_top_left = "+";
            style_edge_top_right = "+";
            style_edge_bottom_left = "+";
            style_edge_bottom_right = "+";
            break;
        }
        case TableStyle::LINED: {
            style_line_horizontal = "━";
            style_line_vertical = "┃";
            style_line_cross = "╋";

            style_t_intersect_right = "┫";
            style_t_intersect_left = "┣";
            style_t_intersect_top = "┳";
            style_t_intersect_bottom = "┻";

            style_edge_top_left = "┏";
            style_edge_top_right = "┓";
            style_edge_bottom_left = "┗";
            style_edge_bottom_right = "┛";
            break;
        }
        case TableStyle::DOUBLE_LINE: {
            style_line_horizontal = "═";
            style_line_vertical = "║";
            style_line_cross = "╬";

            style_t_intersect_right = "╣";
            style_t_intersect_left = "╠";
            style_t_intersect_top = "╦";
            style_t_intersect_bottom = "╩";

            style_edge_top_left = "╔";
            style_edge_top_right = "╗";
            style_edge_bottom_left = "╚";
            style_edge_bottom_right = "╝";
            break;
        }
    }
}
#ifndef CONSOLETABLE_CONSOLETABLEROW_H
#define CONSOLETABLE_CONSOLETABLEROW_H

#include <string>
#include <vector>

class ConsoleTableRow {
public: 

    /// Create a new ConsoleTableRow
    /// \param width How many cells does the row have
    explicit ConsoleTableRow(int width); 

    /// Add a new cell to the ConsoleTableRow
    /// \param data The data of the new cell
    /// \param column The column index of the new cell
    void addEntry(std::string data, int column);

    /// Updates a cell in the ConsoleTableRow with new data
    /// \param data The new data that should be updated
    /// \param column The index of the column that should be updated
    void editEntry(std::string data, int column);

    /// Returns the ConsoleTableRow
    /// \return The vector which holds all entries of the ConsoleTableRow
    std::vector <std::string> getEntry() const&;

private:

    /// The vector which holds all entries of the ConsoleTableRow
    std::vector <std::string> row; 

};


#endif //CONSOLETABLE_CONSOLETABLEROW_H
#include "ConsoleTableRow.h"

ConsoleTableRow::ConsoleTableRow(int width) {
    row.resize(width);
}

void ConsoleTableRow::addEntry(std::string data, int column) {
    row.at(column) = data;
}

std::vector<std::string> ConsoleTableRow::getEntry() const&{
    return row;
}

void ConsoleTableRow::editEntry(std::string data, int column) {
    row.at(column) = data;
}
#ifndef CONSOLETABLE_CONSOLETABLEUTILS_H
#define CONSOLETABLE_CONSOLETABLEUTILS_H

#include <string>
#include <sstream>

class ConsoleTableUtils {
public:

    /// Repeats a given string n times
    /// \param input The string which should be repeated
    /// \param n How many times should the given string be repeated
    /// \return The repeated string
    static std::string repeatString(const std::string &input, int n){
        std::ostringstream os;
        for (int i = 0; i < n; i++)
            os << input;
        return os.str();
    }

};

#endif //CONSOLETABLE_CONSOLETABLEUTILS_H
#include <iostream>
#include <unistd.h>
#include "ConsoleTable.h"

int main() {
    ConsoleTable ct(TableStyle::BASIC, 2); 

    ct.addColumn("Country");
    ct.addColumn("Capital");
    ct.addColumn("Population");
    ct.addColumn("Area");
    ct.addColumn("Currency");

    ConsoleTableRow row1(5);
    row1.addEntry("Germany", 0);
    row1.addEntry("Berlin", 1);
    row1.addEntry("82,800,000", 2);
    row1.addEntry("357,168 km2", 3);
    row1.addEntry("Euro", 4);
    ct.addRow(row1);

     ConsoleTableRow row2(5);
    row2.addEntry("Australia", 0);
    row2.addEntry("Canberra", 1);
    row2.addEntry("24,877,800", 2);
    row2.addEntry("7,692,024 km2", 3);
    row2.addEntry("Australian Dollar", 4);
    ct.addRow(row2);

    ConsoleTableRow row3(5);
    row3.addEntry("China", 0);
    row3.addEntry("Beijing", 1);
    row3.addEntry("1,403,500,365", 2);
    row3.addEntry("9,596,961 km2", 3);
    row3.addEntry("Yuan", 4);
    ct.addRow(row3);

    ConsoleTableRow row4(5);
    row4.addEntry("Iceland", 0);
    row4.addEntry("Reykjavik", 1);
    row4.addEntry("348,580", 2);
    row4.addEntry("102,775 km2", 3);
    row4.addEntry("Icelandic Krona", 4);
    ct.addRow(row4);

    // Print all rows
    ct.printTable();

    sleep(1);

    // Remove entry
    ct.removeRow(1);
    ct.printTable();

    sleep(1);

    // Update entry
    ct.editRow("New Country!",0, 1);
    ct.printTable();

    return 0;
}   
Spelling fixes; use real headers
Source Link
Toby Speight
  • 81.7k
  • 14
  • 101
  • 308

Personally I often prefer console applications over GUI applications. However, sometimes it is quietquite a challenge to display everything well-aligned. Therefore I decided to create a console based-based table which makes it possible to display data organized into categories. You can add, remove and update entries and choose between different table designs. This is an example how it looks like.

enter image description hereenter image description here enter image description hereenter image description here

(Some characters might not be displayed correctly in the windowsWindows console. In the linuxLinux terminal all characters are printed without a problem.)

ConsoleTable.h ##ConsoleTable.h

ConsoleTable.cpp ##ConsoleTable.cpp

ConsoleTableRow.h ##ConsoleTableRow.h

ConsoleTableRow.cpp ##ConsoleTableRow.cpp

ConsoleTableUtils.h ##ConsoleTableUtils.h

ConsoleTableUtils.cpp ##ConsoleTableUtils.cpp

The project repository can be found hereon GitHub.

Personally I often prefer console applications over GUI applications. However, sometimes it is quiet a challenge to display everything well-aligned. Therefore I decided to create a console based table which makes it possible to display data organized into categories. You can add, remove and update entries and choose between different table designs. This is an example how it looks like.

enter image description here enter image description here

(Some characters might not be displayed correctly in the windows console. In the linux terminal all characters are printed without a problem)

ConsoleTable.h

ConsoleTable.cpp

ConsoleTableRow.h

ConsoleTableRow.cpp

ConsoleTableUtils.h

ConsoleTableUtils.cpp

The project repository can be found here.

Personally I often prefer console applications over GUI applications. However, sometimes it is quite a challenge to display everything well-aligned. Therefore I decided to create a console-based table which makes it possible to display data organized into categories. You can add, remove and update entries and choose between different table designs. This is an example how it looks like.

enter image description here enter image description here

(Some characters might not be displayed correctly in the Windows console. In the Linux terminal all characters are printed without a problem.)

##ConsoleTable.h

##ConsoleTable.cpp

##ConsoleTableRow.h

##ConsoleTableRow.cpp

##ConsoleTableUtils.h

##ConsoleTableUtils.cpp

The project repository can be found on GitHub.

Add more tag and improve one link.
Source Link
766F6964
  • 901
  • 1
  • 6
  • 22
Loading
Tweeted twitter.com/StackCodeReview/status/980686904852140032
added 3067 characters in body
Source Link
766F6964
  • 901
  • 1
  • 6
  • 22
Loading
Source Link
766F6964
  • 901
  • 1
  • 6
  • 22
Loading