Shadowhope Shadowhope - 2 months ago 18
C++ Question

iomanip formatting for multiple inputs and dollar signs - C++

I'm having some issues producing this output for my code.

Apples
10 @ 0.98/UNIT: $9.80
Bananas
1 @ 1.29/UNIT: $1.29
Flank Steak
1 @ 8.82/UNIT: $8.82
Chocolate Ice Cream
1 @ 3.23/UNIT: $3.23
Gym Bag
1 @ 23.12/UNIT: $23.12
ORDER TOTAL:************************************$46.26


My issue is with the alignment of the decimal places for the totals with the dollar sign attached. I'm supposed to be able to do it with raw setw() code and right, left alignment, but I'm not so sure how to go about it without getting spaces between the $ and the actual numerical value.

Here's what I've gotten so far..

void printReceipt(const int cart[], const string productName[], const double prices[], int productCount){
double orderTotal = 0;
for (int i = 0; i < productCount; i++){ //Loop for output of receipt
if (cart[i] != 0){ //Will not output for item not ordered.
cout << productName[i] << endl;
cout << fixed << setprecision(2)
<< setw(3) << left << cart[i]
<< setw(3) << " @ " //Formatting for receipt print
<< setw(6) << prices[i]
<< setw(35) << left << "/UNIT:" << "$"
<< setw(6)<< right << (cart[i] * prices[i]) << endl;
orderTotal = orderTotal + (cart[i] * prices[i]);
}}
cout << fixed << setfill('*') << setw(47)<< left << "ORDER TOTAL:";
cout << setfill(' ') << "$" << setw(6) << right << setprecision(2) << orderTotal;
}


current output is as follows

Apples
5 @ 0.98/UNIT: $ 4.90
Bananas
5 @ 1.29/UNIT: $ 6.45
Flank Steak
5 @ 8.82/UNIT: $ 44.10
Chocolate Ice Cream
5 @ 3.23/UNIT: $ 16.15
Gym Bag
5 @ 23.12/UNIT: $115.60
ORDER TOTAL:***********************************$187.20

Answer

You will have to do this as a two-step process.

  1. Format the dollar amount (cart[i]*prices[i]) into a std::ostringstream, using only the setprecision manipulator. No minimum setw, so all you get is the formatted amount. Obtain the string representation from the std::ostringstream, using str().

  2. By using the length of the string that's returned from str(), you can calculate the amount of padding needed to position the '$'.

Instead of the fixed setw(35), you will compute the padding for this field. Just as a rough estimate, this will probably be:

<< setw(42-amount.length()) << left << "/UNIT:" << "$" << amount << std::endl;

where amount is the formatted std::string you obtained in step 1. In this manner, the width here will automatically adjust to give the appropriate amount of room for the amount.

This, by itself will not adjust for the unit count at the beginning of the line, which is also variable length. But after handling the amount correctly, here, you should be able to figure out how to fix that in the same manner.