How to get this format?

Need some help.I'm suppose to create a table based on the information shown below. The sample output is supposed to look like this:

---------------------------------------------------------
No.   | Enrollment No.     | Score               | Grade
---------------------------------------------------------
1.      145699               89.00                  A
2.      456987               76.50                  B+
3.      118989                4.50                  F
---------------------------------------------------------


There are about twenty students to be filled into the list.
I used <iomanip> to format the ouput, but I encounter three problems:
One: The grade is no aligned to the left. If I used setiosflags(ios::left), the grade is printed directly next to the score -- which makes it worse.
Two: From the No. 10 onwards, all alignments are off.
Three: The enrollment number is printed in scientific form

This is a snippet of the code (non-relevant parts are cut out):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <iomanip>
const int Size = 20;
using namespace std;

void main()
{
  // This is suppose to be done by cin...
  float enrollment_number[Size] = {145690, 176899, 678191, 145670, 234760,
                                   389156, 456800, 776541, 345689, 222345,
                                   156456, 485912, 456982, 445628, 123981,
                                   456720, 567234, 356709, 765123, 267810};
  float score[Size] = { 89.00, 45.50, 12.00, 96.00, 60.00,
                        78.50, 54.50, 80.00, 30.00, 36.50,
                        56.50, 22.00, 67.00, 87.00, 78.00,
                        67.80, 70.00, 74.00, 90.00, 81.00 };
  string grade[Size] = { "A", "C", "F", "A", "B",
                         "A-", "C+", "A", "D", "D+",
                         "B-", "D-", "B+", "A", "A-",
                         "B+", "A-", "A-", "A", "A" };

  cout << setw(80) << setfill('-') << "\n";
  cout << setfill(' ') << "No." << setw(7) << "|Name" << setw(20) << "|Score" << setw(20) << "|Grade\n";
  cout << setw(80) << setfill('-') << "\n";

  // This is the where the problem starts...
  for (int i = 0; i < Size; i++)
  {
    cout << setfill(' ') << i+1 << "." << setw(10) << enrollment_number[i] << setw(18);
    cout << setiosflags(ios::fixed) << setprecision(2) << score[i] << resetiosflags(ios::fixed);
    cout << setw(15) << grade[i] << endl;
  }
}


My rather disasterous output...

-------------------------------------------------------------------------------
No.  |Name              |Score             |Grade
-------------------------------------------------------------------------------
1.    145690             89.00              A
2.   1.8e+05             45.50              C
3.   6.8e+05             12.00              F
4.   1.5e+05             96.00              A
5.   2.3e+05             60.00              B
6.   3.9e+05             78.50             A-
7.   4.6e+05             54.50             C+
8.   7.8e+05             80.00              A
9.   3.5e+05             30.00              D
10.   2.2e+05             36.50             D+
11.   1.6e+05             56.50             B-
12.   4.9e+05             22.00             D-
13.   4.6e+05             67.00             B+
14.   4.5e+05             87.00              A
15.   1.2e+05             78.00             A-
16.   4.6e+05             67.80             B+
17.   5.7e+05             70.00             A-
18.   3.6e+05             74.00             A-
19.   7.7e+05             90.00              A
20.   2.7e+05             81.00              A



No matter how I fix it, I only end up making it worse. And so far, this is the nicest ouput I can get. I believe I might have done some mistakes.
How can I fix it and get it exactly like the sample output?
Thanks.
Last edited on
I managed to correct.
I'm a little surprised that this compiled ( line 31 caused a problem ) but I'll get to that later.

1. void main() is not legal code although many compilers will accept it. main() returns an integer so change line 6 to int main()

2. The problem with the scientific notation is that you have declared enrollment_number as a float so change the type toint or unsigned int.

3. The setfill(' ') part of line 29 can be moved to just before the for loop since you never need any other padding character for the rest of the program.

4. The alignment problem for No. 10 onward arises from the extra digit pushing everything to the right one extra space. If you didn't need the period you could simply set a field width and left alignment before outputting No. but the period complicates things. Here's one solution:

1
2
3
    cout << ( i < 9 ? setw(1) : setw(2) ) << i+1 
           <<  ( i < 9 ? setw(6) : setw(5) ) << left << "."
           << setw(10) << enrollment_number[i] << setw(18);


For index number i between 0 and 8 (No. between 1 and 9) we use a field width of one and for No. 10 or greater a field width of 2. We do the same type of thing when outputting the period so the total field width is the same in both cases. Note this alignment will break if No. could be three digits. In that case you might want to convert No. plus the period into a string using a stringstream.

5. Your sample output has a space between the vertical bar and the field name in the table header, but your output does not. Also the second field name is Enrollment No. in the sample output whereas your program used Name.

6. Line 31 would not compile for me because the compiler could not find the output operator << taking std::string as an argument. You need to add #include <string>.

7. Line 13, your declaration of score caused a compiler warning about possible loss of information. This is because you have declared score to be a float but by default floating point literals like 89.00 are doubles so the compiler is converting those double values to floats. In this particular case there is no loss of information, but you can get rid of the warning by declaring score as a double.

8. The field widths for the table values still do not quite align with the header widths but I'll leave that for you to fix.

Actually in looking at point 4 above it would probably easier to just use a regular if statement instead of the conditional operator.

1
2
3
4
5
6
7
8
9
if ( i < 9 )
{
    cout << setw(1) <<  i+1 <<  setw(6) << left << ".";
}
else
{
    cout << setw(2) <<  i+1 << setw(5) << left << ".";
}
cout << setw(10) << enrollment_number[i] << setw(18);
Topic archived. No new replies allowed.