c++structure

C++ structure value displaying in wrong field


I am trying to print the values within a structure as a table. However, one of the names gets printed out into the wrong 'field'.

Here is what I have:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct SPlayer {
    string name;
    string team;
    int goalsScored;
    int yellowcards;
    int redcards;
};

void PrintHeader() {
    cout << "name\t\tteam\tgoals\tyellow cards\tred cards\n";
    cout << "--------------------------------------------------------------------" << endl;
}

void PrintTable(SPlayer table) {
    cout << table.name << "\t\t" << table.team << "\t" << table.goalsScored << "\t" << table.yellowcards << "\t\t" << table.redcards << endl;
}

int main()
{
    SPlayer mitchell = { "Mitchell" , "Red" , 4 , 1 , 0 };
    SPlayer smith = { "Smith" , "Blue" , 8 , 0 , 0 };
    SPlayer white = { "White" , "Green" , 0 , 2 , 4 };
    SPlayer doe = { "Doe" , "Yellow" , 2 , 1 , 0 };

    vector<SPlayer> players;
    players.push_back(mitchell);
    players.push_back(smith);
    players.push_back(white);
    players.push_back(doe);
    
    PrintHeader();

    for (int i = 0; i < players.size(); i++) {
        PrintTable(players.at(i));
    }
}

When you run the code, it looks like this:

terminal showing the values within a structure printed as a table

Does anyone know how to fix this?


Solution

  • Do not use \t characters to format your table columns. It moves the cursor to the next even multiple of the console's tab spacing, which in your case appears to be 8 characters.

    Mitchell is already 8 characters long, so the following \t moves the cursor to position 16, and the next \t moves it to position 24. So you output Red in the wrong place.

    Whereas Smith is only 5 characters, so the following \t moves the cursor to position 8, and the next \t moved it to position 16. So you output Blue in the expected place.

    And so on.

    If either the player name or team name exceeds the tab spacing, your table formatting gets messed up, which is exactly what you see happening in your screenshot:

    tab spaces

    Instead, you should use the std::setw() stream manipulator to specify the exact sizes of your columns. That will reserve space that cout can then fill in with your string values, eg:

    ...
    #include <iomanip>
    ...
    
    void PrintHeader() {
        cout << left;
        cout << setw(16) << "name"
             << setw(8)  << "team"
             << setw(8)  << "goals"
             << setw(16) << "yellow cards"
             << setw(20) << "red cards"
             << '\n';
        cout << "--------------------------------------------------------------------" << endl;
    }
    
    void PrintTable(const SPlayer &table) {
        cout << left;
        cout << setw(16) << table.name
             << setw(8)  << table.team
             << setw(8)  << table.goalsScored
             << setw(16) << table.yellowcards
             << setw(20) << table.redcards
             << '\n';
    }
    

    Online Demo

    reserved sizes

    Just be sure to use column sizes that are large enough to accommodate each column's longest string value.