Barton E
Barton E

Reputation: 11

Aligning columns using set-width

I am trying to get this C++ assignment aligned properly. The main goal is to properly read data from a file, which is being done, but the output is not aligned properly.

Somebody has suggested putting all the variables into one string and outputting that row by row, but that seems like I would need to re-write the majority of the program and I'm not completely sure how to do it. I have attached the code and what the output looks like below. Just wondering if there's a better way to keep everything aligned while using setwidth, or another basic alignment method if one exists. By the way, the file's input can change.

    while (!PatientsFile.eof()) {
    PatientsFile >> firstName; 
    PatientsFile >> lastName;
    PatientsFile >> pulse;
    PatientsFile >> respir;
    PatientsFile >> oxygen;
    PatientsFile >> room;

    string name = firstName + ", " + lastName;

    //patient info
    cout << setw(4) << room << ' ';
    cout << name;

    //pulse
    if (pulse >= 101) {
        cout << setw(13) << "High=" << pulse << ' ';
        dangerCount++; }
    else if (pulse <= 59) {
        cout << setw(16) << "Low=" << pulse << ' ';
        dangerCount++; }
    else {
        cout << setw(19) << pulse << ' '; }

    //respir
    if (respir >= 21) {
        cout << setw(5) << "High=" << respir << ' ';
        dangerCount++; }
    else if (respir <= 10) {
        cout << setw(6) << "Low=" << respir << ' ';
        dangerCount++; }
    else {
        cout << setw(7) << respir << ' '; }

    //oxygen
    if (oxygen >= 101) {
        cout << setw(7) << "High=" << oxygen << ' ';
        dangerCount++; }
    else if (oxygen <= 91) {
        cout << setw(5) << "Low=" << oxygen << ' ';
        dangerCount++; }
    else {
        cout << setw(7) << oxygen << ' '; }

    //dangerCount
    if (dangerCount == 1) {
        checkTotal++;
        cout << "CHECK\n";}
    else if (dangerCount == 2) {
        alertTotal++;
        cout << "ALERT***\n"; }
    else if (dangerCount == 3) {
        criticalTotal++;
        cout << setw(15) << "CRITICAL****\n"; }
    else {
        normalTotal++;
        cout << endl; }
    dangerCount = 0;
    }
    //display totals
    cout << endl << normalTotal << " Normal\n";
    cout << alertTotal << " ALERT\n";
    cout << checkTotal << " CHECK\n";
    cout << criticalTotal << " CRITICAL\n";

Output:

Room Name                       Pulse  Respir  Oxygen    
-----------------------------------------------------
 111 Pete, Moss            Low=59      11  Low=91 ALERT***
 312 Diana, Canser        High=107   Low=10      96 ALERT***
 332 Willie, Makit        High=123 High=30      94 ALERT***
 111 Betty, Wont            Low=50   Low=10  Low=90   CRITICAL****
 331 Freda, Spirit        High=110 High=23  Low=90   CRITICAL****
 321 Wilma, Moneylast        High=132      18  Low=88 ALERT***
 121 Robin, Banks            Low=59      20     100 CHECK
 122 Charlie, Horse            Low=56      15      95 CHECK
 121 Eileen, Back            Low=45      17  Low=88 ALERT***
 222 Eaton, Buggs                 79      16      97 
 222 Summer, Day                 60      12      92 
 231 Bea, Sting                 73 High=21  Low=91 ALERT***
 311 Anita, Bath        High=111 High=33      97 ALERT***
 232 April, Showers                 61 High=22      93 CHECK
 222 Rose, Bush                100      20     100 
 231 Buster, Leggs                 88 High=44  Low=88 ALERT***
 221 Barb, Wire                 60      12  Low=82 CHECK
 322 Jim, Shoos        High=101      19      94 CHECK
 322 Kris, Mass            Low=4      14      99 CHECK
 222 Rich, Bright                 77      16      92 

4 Normal
8 ALERT
6 CHECK
2 CRITICAL

Upvotes: 1

Views: 448

Answers (2)

Meiogordo
Meiogordo

Reputation: 124

As Xion's answer mentioned, the process of hardcoding the correct value for the for the text to be aligned correctly, is tedious. Furthermore, it might even not be correct at all for a different data set - For example, what would happen if someone had a much larger name than anticipated?

My suggestion is the following: Iterate over the data completely once, and store the maximum width of each field in a separate variable (also storing the data retrieved).

After that, you could then loop once again over the input, and now everything would be correctly aligned, as you would now know the maximum width of each field (including not having the guess the correct spacing for the header column beforehand, which would be ideal).

You could either create objects of this information and store them in a std::vector, or do the same with each separate data field, having a vector for each one.

Upvotes: 1

Xion
Xion

Reputation: 374

You can try using tab \t in order to align your list correctly. Here is the link you might want to look at: How many spaces for tab character(\t)?

Otherwise you will have to do

cout << "text" << setw(#) << "text" << setw(#) << endl;

I would advise against this since it just hardcoding set numbers and its tedious because you would have to count and make sure it is matching correctly.

Upvotes: 2

Related Questions