Recall the syntax to output data:
cout << expression << expression ...;
Which allows any expression
(data) to be output in its raw form, but sometimes this raw data needs to be formatted. Data may need to be limited in decimal places such as with money. Many calculations results may need to be output, and having the data line up on the output could make things much cleaner to look at. The <iomanip>
library enables these types of manipulations to occur.
To use any of the operations discussed in this post the <iomanip>
library must be included with a preprocessor directive:
#include <iomanip>
To manipulate the amount of digits shown of floating-point values use:
Which will set the amount of digits shown of a floating-point number to the passed int
. To fully understand what setprecision is doing first consider the following snippet:
double d1 = 12345.6789, d2 = 123456.789, d3 = 1234567.89; cout << "d1 = " << d1 << endl << "d2 = " << d2 << endl << "d3 = " << d3 << endl;
Which outputs:
d1 = 12345.7 d2 = 123457 d3 = 1.23457e+06
It can be seen that by default C++ will only show 6 digits of a floating-point number. If the whole number does not take up all 6 digits, then part of the fraction is shown like d1
, but if the whole number takes up the 6 digits then then none of the fraction is shown like d2
. Then if the whole number takes more than 6 digits it can not be displayed in fixed-point notation, so the number is shown in scientific notation using only 6 of the digits (essentially displaying a close enough number). This point can be changed with setprecision()
. For example:
double d1 = 12345.6789, d2 = 123456.789, d3 = 1234567.89; cout << setprecision(1) << "d1 = " << d1 << endl << "d2 = " << d2 << endl << "d3 = " << d3 << endl;
Which outputs:
d1 = 1e+04 d2 = 1e+05 d3 = 1e+06
Each number is only shown with 1 digit in scientific notation since setprecision(1)
was used. Since every number has a whole number that takes up more than 1 digit, the first digit of each number is shown and the rest of the number shown in scientific notation. It should be noted that once this behavior is set it will not change. Thus even if there were 2 separate cout
statements:
double d1 = 12345.6789, d2 = 123456.789, d3 = 1234567.89; cout << setprecision(1); cout << "d1 = " << d1 << endl << "d2 = " << d2 << endl << "d3 = " << d3 << endl;
The same output would be produced.
This behavior can be changed to allow setprecision()
to refer to how many digits of the fraction to show by using one of two manipulators:
Operator | Description |
---|---|
scientific | Displays output floating-point numbers in scientific notation |
fixed | Displays output floating-point numbers in fixed-point notation |
The fixed
and scientific
manipulators will force all floating-point numbers to be output in either notation respectively until the other manipulator is used, or the manipulator is unset. When either of these manipulators is used it will change setprecision()
to choosing how many digits of the fraction to show of output floating-point values. Thus, the following code:
double d1 = 12345.6789, d2 = 123456.789, d3 = 1234567.89; cout << setprecision(1) << fixed; cout << "d1 = " << d1 << endl << "d2 = " << d2 << endl << "d3 = " << d3 << endl;
Outputs:
d1 = 12345.7 d2 = 123456.8 d3 = 1234567.9
And the following code:
double d1 = 12345.6789, d2 = 123456.789, d3 = 1234567.89; cout << setprecision(1) << scientific; cout << "d1 = " << d1 << endl << "d2 = " << d2 << endl << "d3 = " << d3 << endl;
Outputs:
d1 = 1.2e+04 d2 = 1.2e+05 d3 = 1.2e+06
To go back to the original settings use either:
cout.unsetf(ios::fixed)
To unset the fixed
manipulator, or use:
cout.unsetf(ios::scientific)
To unset the scientific
manipulator. The precision of digits can be reset by simply resetting the precision back to 6 using:
setprecision(6)
So to read in a number from the user, change the precision to 2, show the value in fixed-point notation, then scientific-notation, then show using default behavior the following snippet could be used:
double value = 0.0; cout << “Enter a number: “; cin >> value; cout << setprecision(2) << "fixed: " << fixed << value << endl << "scientific: " << scientific << value << endl; cout.unsetf(ios::scientific); cout << "default: " << setprecision(6) << value << endl;
To set how many spaces at minimum the next piece of data to be output will take up use:
Which will provide a space for the next expression output that is at minimum the int
passed wide. If the next expression to be output takes up more spaces than provided with the setw()
then the extra space will just be given to the expression (effectively breaking out of the end of the setw()
). This is primarily used to line up data and to make the same character be output many times.
For example, take the following code:
const double pi = 3.14, radius = 6.7, height = 10; double circumference = 2 * pi * radius; double area = pi * pow(radius, 2); double volume = area * height; cout << "circumference: " << circumference << endl << "area: " << area << endl << "volume: " << volume << endl;
Which outputs:
circumference: 42.076 area: 140.955 volume: 1409.55
Although there are only 3 values being output it can already be seen that the output is becoming a mess. With each calculation that gets added the calculated results become more all over the output, all depending on the size of the label. With setw()
the output can be cleaned up to show a column of labels and a column of results.
First, the labels can all take up the same space by using a value for setw()
that provides the same space for each label. The amount of characters in the largest label needs to be counted, then a few spaces need to be added so the largest label has some padding to it too. The largest label in this example is circumference
which has 13 characters so a width of 20 should be sufficient.
const double pi = 3.14, radius = 6.7, height = 10; double circumference = 2 * pi * radius; double area = pi * pow(radius, 2); double volume = area * height; cout << setw(20) << "circumference" << circumference << endl << setw(20) << "area" << area << endl << setw(20) << "volume" << volume << endl;
Which outputs:
circumference42.076 area140.955 volume1409.55
By default setw()
will justify content to the right. This behavior can be changed with the manipulators:
Operator | Description |
---|---|
left | Justifies setw() content left. |
right | Justifies setw() content right. |
So to add left
justification to the labels in the program:
const double pi = 3.14, radius = 6.7, height = 10; double circumference = 2 * pi * radius; double area = pi * pow(radius, 2); double volume = area * height; cout << left << setw(20) << "circumference" << circumference << endl << setw(20) << "area" << area << endl << setw(20) << "volume" << volume << endl;
Which outputs:
circumference 42.076 area 140.955 volume 1409.55
To line the calculated values up on the right hand side setw()
can be used with a big enough number, for this example we will choose 15:
const double pi = 3.14, radius = 6.7, height = 10; double circumference = 2 * pi * radius; double area = pi * pow(radius, 2); double volume = area * height; cout << left << setw(20) << "circumference" << setw(15) << circumference << endl << setw(20) << "area" << setw(15) << area << endl << setw(20) << "volume" << setw(15) << volume << endl;
Which outputs:
circumference 42.076 area 140.955 volume 1409.55
Which is no different than before. This is because everything is still being justified left inside of the widths. To justify the calculated value to the right
the manipulator must be used:
const double pi = 3.14, radius = 6.7, height = 10; double circumference = 2 * pi * radius; double area = pi * pow(radius, 2); double volume = area * height; cout << left << setw(20) << "circumference" << setw(15) << right << circumference << endl << setw(20) << "area" << setw(15) << area << endl << setw(20) << "volume" << setw(15) << volume << endl;
Which outputs:
circumference 42.076 area 140.955 volume 1409.55
The right
comes after outputting the "circumference"
label thus the earlier left
applies to the "circumference"
label and the right
to all the rest of the data that follows it. Thus to achieve all the labels lining up to the left, and all the calculated values lining up on the right, left
and right
manipulators must be alternated before each respective piece of data needs to be output:
const double pi = 3.14, radius = 6.7, height = 10; double circumference = 2 * pi * radius; double area = pi * pow(radius, 2); double volume = area * height; cout << left << setw(20) << "circumference" << setw(15) << right << circumference << endl << setw(20) << left << "area" << right << setw(15) << area << endl << left << setw(20) << "volume" << setw(15) << right << volume << endl;
Which outputs:
circumference 42.076 area 140.955 volume 1409.55
By default setw()
uses the ' '
(space) as the fill in the spots of the width that the piece of data placed into the width do not take up. This can be changed using:
Which will change the character of the spaces not taken up in the widths that come after this manipulator to whatever char
is passed to it.
For example, to make the area and volume rows have a fill of '.'
in the empty spaces of the widths for the 2 rows:
const double pi = 3.14, radius = 6.7, height = 10; double circumference = 2 * pi * radius; double area = pi * pow(radius, 2); double volume = area * height; cout << left << setw(20) << "circumference" << setw(15) << right << circumference << endl << setfill('.') << setw(20) << left << "area" << right << setw(15) << area << endl << left << setw(20) << "volume" << setw(15) << right << volume << endl;
Which outputs:
circumference 42.076 area........................140.955 volume......................1409.55
Since the output for the circumference comes prior to the setfill()
the new fill does not apply to its widths. But since the area and volume output comes after the setfill()
the new fill does apply to it. To apply the fill to all the rows the setfill()
simply needs to go before all of the output:
const double pi = 3.14, radius = 6.7, height = 10; double circumference = 2 * pi * radius; double area = pi * pow(radius, 2); double volume = area * height; cout << left << setw(20) << "circumference" << setw(15) << right << circumference << endl << setfill('.') << setw(20) << left << "area" << right << setw(15) << area << endl << left << setw(20) << "volume" << setw(15) << right << volume << endl;
Which outputs:
circumference................42.076 area........................140.955 volume......................1409.55
In the game Old School Runescape to calculate the max hit your character can do the effective strength level of the character first needs to be calculated, then the max hit can be calculated. Write a calculator that calculates the effective strength and max hit, with and without potion and armor bonuses, of someones character based on their strength level.
To start, the strength level of the character needs to be read in:
#include <iostream> using namespace std; int main() { // variables int level = 0; // read strength level cout << "Strength level: "; cin >> level; return 0; }
The strength level can then be used to calculate the effective strength level of the character with the formula:
First a potionBonus
is added to the strength level of the player. For the sake of this example the only potion we will have is a strength potion which gives a bonus of 3
. The voidBonus
is a bonus applied if you are wearing a special set of armor and always provides a bonus of 1.1
. With 2 bonuses there are 4 permutations of calculating the effective strength (no bonuses, each bonus on, both bonuses on) which can be added to the program:
#include <iostream> #include <cmath> using namespace std; int main() { // variables int level = 0; double potionBonus = 3, voidBonus = 1.1; // read strength level cout << "Strength level: "; cin >> level; // calculate effective strength levels int noBonusEffectiveStrength = floor(level) + 8; int potionBonusEffectiveStrength = floor(level + potionBonus) + 8; int voidBonusEffectiveStrength = floor((floor(level) + 8) * voidBonus); int bothBonusEffectiveStrength = floor((floor(level + potionBonus) + 8) * voidBonus); return 0; }
Since floor()
is used the <cmath>
library is first included. Then, arithmetic for each bonus is left out in the respective calculations for the proper values to be calculated of all 4 permutations of effective strength with and without bonuses. The 4 effective strength levels can then be output in a table using <iomanip>
:
#include <iostream> #include <cmath> #include <iomanip> using namespace std; int main() { // variables int level = 0; double potionBonus = 3, voidBonus = 1.1; string separator = "+----------+-------------------+-----------------+----------------+\n"; // read strength level cout << "Strength level: "; cin >> level; // calculate effective strength levels int noBonusEffectiveStrength = floor(level) + 8; int potionBonusEffectiveStrength = floor(level + potionBonus) + 8; int voidBonusEffectiveStrength = floor((floor(level) + 8) * voidBonus); int bothBonusEffectiveStrength = floor((floor(level + potionBonus) + 8) * voidBonus); // output effective strength table cout << "\nEFFECTIVE STRENGTH:\n" << separator << "| No Bonus | With Strength Pot | With Void Armor | With Pot/Armor |\n" << separator << left << "| " << setw(8) << noBonusEffectiveStrength << " | " << setw(17) << potionBonusEffectiveStrength << " | " << setw(15) << voidBonusEffectiveStrength << " | " << setw(14) << bothBonusEffectiveStrength << " |\n" << separator; return 0; }
First, the <iomanip>
library is included so the table can be created. A separator
variable is then added as a string that can be output which holds the bar that perfectly separates the rows/columns. The separator
is then output, followed by the headers for the data in the table, followed by another separator
. Then, the '|'
character is used with strategic spacing to separate the different effective strength bonuses, and setw()
is used to keep the effective bonuses in line with the headers previously output regardless of the size of the effective strength. After this row a final separator
is output to close the table off.
The max hit can then be calculated based on the effective strength using the formula:
The max hit formula can be applied to each of the effective strengths to calculate each of the max hits for the respective effective strengths. The max hits can then be output in a table similar to how the effective strengths were:
#include <iostream> #include <cmath> #include <iomanip> using namespace std; int main() { // variables int level = 0; double potionBonus = 3, voidBonus = 1.1; string separator = "+----------+-------------------+-----------------+----------------+\n"; // read strength level cout << "Strength level: "; cin >> level; // calculate effective strength levels int noBonusEffectiveStrength = floor(level) + 8; int potionBonusEffectiveStrength = floor(level + potionBonus) + 8; int voidBonusEffectiveStrength = floor((floor(level) + 8) * voidBonus); int bothBonusEffectiveStrength = floor((floor(level + potionBonus) + 8) * voidBonus); // output effective strength table cout << "\nEFFECTIVE STRENGTH:\n" << separator << "| No Bonus | With Strength Pot | With Void Armor | With Pot/Armor |\n" << separator << left << "| " << setw(8) << noBonusEffectiveStrength << " | " << setw(17) << potionBonusEffectiveStrength << " | " << setw(15) << voidBonusEffectiveStrength << " | " << setw(14) << bothBonusEffectiveStrength << " |\n" << separator; // calculate max hits int noBonusMaxHit = 0.5 + noBonusEffectiveStrength / 10.0; int potionBonusMaxHit = 0.5 + potionBonusEffectiveStrength / 10.0; int voidBonusMaxHit = 0.5 + voidBonusEffectiveStrength / 10.0; int bothBonusMaxHit = 0.5 + bothBonusEffectiveStrength / 10.0; // output max hits table cout << "\nMAX HIT:\n" << separator << "| No Bonus | With Strength Pot | With Void Armor | With Pot/Armor |\n" << separator << "| " << setw(8) << noBonusMaxHit << " | " << setw(17) << potionBonusMaxHit << " | " << setw(15) << voidBonusMaxHit << " | " << setw(14) << bothBonusMaxHit << " |\n" << separator; return 0; }
When compiled and run and provided with the input 90
for the strength level, the program produces the following interaction:
Strength level: 90 EFFECTIVE STRENGTH: +----------+-------------------+-----------------+----------------+ | No Bonus | With Strength Pot | With Void Armor | With Pot/Armor | +----------+-------------------+-----------------+----------------+ | 98 | 101 | 107 | 111 | +----------+-------------------+-----------------+----------------+ MAX HIT: +----------+-------------------+-----------------+----------------+ | No Bonus | With Strength Pot | With Void Armor | With Pot/Armor | +----------+-------------------+-----------------+----------------+ | 10 | 10 | 11 | 11 | +----------+-------------------+-----------------+----------------+
See operations above
What library must be included to use manipulators like setw
, fixed
, and setprecision
?
When outputting floating-point numbers without formatting, how many digits are usually shown?
Why might the default floating-point output be confusing for users?
What does setprecision(4)
mean if neither fixed
nor scientific
is applied?
What does setprecision(4)
mean if fixed
is applied?
How does setprecision(4)
behave when scientific
is applied?
How do you remove the fixed
manipulator once it has been applied?
Which manipulator controls the minimum number of spaces used to display a value?
If you output a string larger than the width specified by setw()
, what happens?
What happens if you output a string smaller than the width specified by setw()
?
Which manipulator controls whether output is aligned to the left or right?
What is the default justification for numeric output when using setw()
?
How can you print numbers so they are always aligned neatly in columns?
Which manipulator allows you to change the character used to pad empty space?
How long does the effect of setfill()
last?
How long does the effect of setw()
last?
How long does the effect of left
last?
How long does the effect of right
last?
How long does the effect of setprecision()
last?
How long does the effect of fixed
last?
How long does the effect of scientific
last?
Give an example where setw()
would be useful when displaying data.
Give an example where setfill()
would improve the readability of output.
Why might a scientist use scientific
formatting for output?
Why might a banker use fixed
formatting for output?
What does cout.unsetf(ios::scientific)
do?
What would happen if you tried to display π with only setprecision(2)
and no fixed
?
What would happen if you displayed π with setprecision(2)
and fixed
?
What is the difference between “field width” and “precision”?
Why is it better to format program output than to rely on defaults?
Which manipulators are sticky (persist across outputs) and which are not?
Explain why setw()
must be reapplied for each new value.
Why does C++ switch to scientific notation automatically for some numbers when neither fixed
nor scientific
is used?
Why does setprecision()
behave differently depending on whether no manipulator, fixed
or scientific
is active?
Why might you need to call unsetf(ios::fixed)
in the middle of a program?
If you forget to reset formatting manipulators, what unintended consequences might occur later in the program’s output?
Why does setw()
not persist, while setfill()
does?
How can the combination of setw()
, left
, and setfill()
be used to design custom table layouts in console programs?
What would happen if you used setfill('0')
with numeric output? How might this be useful?
Why is fixed
formatting important when displaying monetary values like prices or totals?
Why is scientific
formatting useful when dealing with values close to zero?
How does precision affect rounding, and why might this be important in scientific calculations?
What happens if you set a very large field width with setw()
for a small number or string?
What happens if you set a very small field width with setw()
for a large number or string?
How could poor use of output manipulators make program results misleading?
In what situation would it be important to show more decimal places than usual?
In what situation would it be important to reduce the number of decimal places?
Why should programmers consider readability when outputting program results?
How do manipulators in <iomanip>
improve the professional quality of a program’s output?
Why might it be dangerous to assume the default formatting is “good enough” for scientific data?
int main() { cout << "Pi = " << 3.14159 << fixed << setprecision(2) << endl; return 0; }
int main() { cout << "Pi = " << setprecision(2) << 3.14159 << endl; return 0; }
#include <iostream> #include <iomanip> using namespace std; int main() { cout << setw(10) << "Name" << "Age" << endl; cout << setw(10) << "Bob" << 25 << endl; return 0; }
#include <iostream> #include <iomanip> using namespace std; int main() { cout << setfill('*'); cout << setw(10) << "Item" << setw(10) << 15 << endl; cout << setw(10) << "Tax" << setw(10) << 2.5 << endl; cout << setw(10) << "Total" << setw(10) << 17.5 << endl; return 0; }
#include <iostream> #include <iomanip> using namespace std; int main() { double x = 12345.6789; cout << fixed << scientific << setprecision(2) << x << endl; return 0; }
#include <iostream> #include <iomanip> using namespace std; int main() { cout << "Product" << left << setw(5) << "Price" << endl; cout << "Milk" << setw(10) << 2.5 << endl; cout << "Eggs" << setw(10) << 3.75 << endl; return 0; }
fixed
formatting using unsetf
. Identify and correct the mistake so that the program first prints a number with 3 decimal places and then prints it with default formatting.#include <iostream> #include <iomanip> using namespace std; int main() { double d = 456.789; cout << fixed << setprecision(3) << d << endl; cout << unsetf(ios::fixed) << d << endl; return 0; }
setw()
to a name, but nothing is happening. Correct the program so that the name is right aligned in the setw()
.#include <iostream> #include <iomanip> using namespace std; int main() { cout << "Alice" << setw(10) << endl; return 0; }
setw()
to two names, but only the first name is aligned. Correct the program so that both names appear in neatly right aligned columns.#include <iostream> #include <iomanip> using namespace std; int main() { cout << setw(10) << "Alice" << "Bob" << endl; return 0; }
#include <iostream> using namespace std; int main() { cout << setw(8) << "Test" << endl; return 0; }
.
as the fill character.Ask the user for a starting length in meters. Generate a table of conversions to centimeters (100 in meter), millimeters (1000 in meter), and kilometers (1000 meters is a kilometer). Align all columns with setw()
. Display values with 3 decimal places.
Ask for three employee names, their hours worked, and their pay rate. Calculate pay and print a table:
%
.setw()
and setfill()
.
The formula for monthly payment is: 0.000000632
for red light.)