Problem with <iomanip> alignment.

Mar 13, 2011 at 4:13am
I'm having trouble aligning some text with setw and the left alignment. I'm not sure if it has something to do with the fact that I'm printing from a function. The text within quotes aligns fine, but the output from the function aligns to the right and screws up the placement of the text after it. Here's my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void playerReadout(vector<player> players, int numOfPlayers)
{
	for(int i = 0;i < numOfPlayers;i++)
	{
		cout << "Player #" << (i + 1) << " - (" << players[i].getName() << ")" << endl;
		cout << "---------" << endl;
		cout << left << setw(20) << "HP: " << players[i].getCurrHP() << "/" << players[i].getMaxHP()
			 << setw(20) << "Bloodied: " << players[i].getBloodied() << endl
			 << setw(20) << "Surge Value: " << players[i].getSurgeValue()
			 << setw(20) << "Surges Left: " << players[i].getSurges() << endl;
		cout << "AC: " << players[i].getAC() << endl
			 << "Fortitude: " << players[i].getFort() << endl
			 << "Reflex: " << players[i].getRef() << endl
			 << "Will: " << players[i].getWill() << endl;
		cout << "Initiative Bonus: " << players[i].getInit() << endl;
		cout << "Statuses: ";
		players[i].printStatuses();
		cout << endl;
		cout << "---------" << endl;
		cout << endl;
	}
}


And here's the output I'm having trouble with:


Player #1 - (Rolen)
----------
HP:                   54/59Bloodied:         29
Surge Value:      14Surges Left:       3
AC: 22
Fortitude: 17
Reflex: 20
Will: 18
Initiative Bonus: 8
Statuses: None
----------
Last edited on Mar 13, 2011 at 4:18am
Mar 13, 2011 at 6:27am
I tried changing the cout statements so that it's not all just one big statement, but it had no effect. Any ideas?
Mar 13, 2011 at 7:12am
If it helps, it should look something like:


Player #1 - (Rolen)
----------
HP: 54/59           Bloodied: 29
Surge Value: 14     Surges Left: 3
AC: 22
Fortitude: 17
Reflex: 20
Will: 18
Initiative Bonus: 8
Statuses: None
----------

Last edited on Mar 13, 2011 at 7:12am
Mar 13, 2011 at 9:17am
You should only have one setw per line. Or rather, the problem is the second setw's don't do anything useful, but rather mess up your output.
PS: What you probably want to do is this:
1
2
cout << left << "HP: " << players[i].getCurrHP() <<setw(20) "/" << players[i].getMaxHP()
	           << "Bloodied: " << players[i].getBloodied() << endl;
Last edited on Mar 13, 2011 at 10:45am
Mar 13, 2011 at 1:56pm
No, because with only one setw function call, it will cut off all text after the first 20 characters. It's going to require a setw for each cout statement, but what I don't understand is why the output from my functions are floating to the right when I put a "left" statement in there.
Mar 13, 2011 at 2:59pm
well, why don't you use a simpler solution: "\t"
Mar 13, 2011 at 3:09pm
well, why don't you use a simpler solution: "\t"


Worst suggestion ever. Please reflect on that statement.
Mar 13, 2011 at 3:23pm
Worst suggestion ever. Please reflect on that statement.

Why is it worst ever? How is this not give the output OP wanted?
1
2
cout << "HP: " << 35 << "/" << 56 << "\t\t" << "Bloodied: " << 12 << endl;
cout << "Surge Value: " << 34 << "\t\t" << "Surges Left: " << 35 << endl; 
Mar 13, 2011 at 3:34pm
Exactly, it isn't. The width of a tab is undefined, with setw you can precisely control how it looks like.
Mar 13, 2011 at 3:47pm
So nobody knows why it's doing this?
Mar 13, 2011 at 4:09pm
I see, thanks for that explanation.
Mar 13, 2011 at 4:14pm
Huh, I told you didn't I? Your code is wrong.

hanst99 wrote:
What you probably want to do is this:


1
2
cout << left << "HP: " << players[i].getCurrHP() << "/" <<setw(20)<< players[i].getMaxHP()
	           << "Bloodied: " << players[i].getBloodied() << endl;


EDIT: ohps, mine too. fixed.
Last edited on Mar 13, 2011 at 4:18pm
Mar 13, 2011 at 4:24pm
hanst, you obviously didn't read my response to your original post.
Mar 13, 2011 at 4:27pm
I'm not saying one setw alltogether, but only one setw per line. Please just try that line that I posted and see if that does what you want and fix the other lines accordingly, of course I am not going to write the entire code for you.

And
No, because with only one setw function call, it will cut off all text after the first 20 characters.
no it doesn't. I think you got a wrong impression on what setw does.
Last edited on Mar 13, 2011 at 4:28pm
Mar 13, 2011 at 4:45pm
Yes, and as I stated in my third post, I already tried using multiple statements. Here is my current code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void playerReadout(vector<player> players, int numOfPlayers)
{
	for(int i = 0;i < numOfPlayers;i++)
	{
		cout << "Player #" << (i + 1) << " - (" << players[i].getName() << ")" << endl;
		cout << "---------" << endl;
		cout << setw(20) << left << "HP: " << players[i].getCurrHP() << "/" << players[i].getMaxHP();
		cout << "     ";
		cout << setw(20) << left << "Bloodied: " << players[i].getBloodied() << endl;
		cout << setw(20) << left << "Surge Value: " << players[i].getSurgeValue();
		cout << "     ";
		cout << setw(20) << left << "Surges Left: " << players[i].getSurges() << endl;
		cout << "AC: " << players[i].getAC() << endl
			 << "Fortitude: " << players[i].getFort() << endl
			 << "Reflex: " << players[i].getRef() << endl
			 << "Will: " << players[i].getWill() << endl;
		cout << "Initiative Bonus: " << players[i].getInit() << endl;
		cout << "Statuses: ";
		players[i].printStatuses();
		cout << endl;
		cout << "---------" << endl;
		cout << endl;
	}
}
Mar 13, 2011 at 5:09pm
And that is wrong, as I just told you earlier. setw is a manipulator that makes sure that the next thing that is being inserted into the stream is filled to at least the size of it's parameter. So what this:
cout << setw(20) << left << "HP: "
does is to set the state of cout so that the alignment is left (which means simplified, what you write is on the left side and the fill characters will be on the right) and that the overall width of the next insertion is 20 characters. In this case, this is "HP: " - basically, this means it will insert "HP:" and 17 space characters.
Mar 13, 2011 at 5:14pm
So how can I set the width for both "HP: " and the output from the function?
Mar 13, 2011 at 5:19pm
You call setw after the function. If you want to make sure that 20 is the overall width of the entire string, convert the output to a string via a stringstream before making the output.
Topic archived. No new replies allowed.