In this section, we will look at various aspects of the iostream output class (ostream).
Note: All of the I/O functionality in this lesson lives in the std namespace. That means all I/O objects and functions either have to be prefixed with “std::”, or the “using namespace std;” statement has to be used.
The insertion operator
The insertion operator (<<) is used to put information into an output stream. C++ has predefined insertion operations for all of the built-in data types, and you've already seen how you can overload the insertion operator for your own classes.
In the lesson on streams, you saw that both istream and ostream were derived from a class called ios. One of the jobs of ios (and ios_base) is to control the formatting options for output.
Formatting
There are two ways to change the formatting options: flags, and manipulators. You can think of flags as boolean variables that can be turned on and off. Manipulators are objects placed in a stream that affect the way things are input and output.
To switch a flag on, use the setf() function, with the appropriate flag as a parameter. For example, by default, C++ does not print a + sign in front of positive numbers. However, by using the std::ios::showpos flag, we can change this behavior:
1 2 |
std::cout.setf(std::ios::showpos); // turn on the std::ios::showpos flag std::cout << 27 << '\n'; |
This results in the following output:
+27
It is possible to turn on multiple ios flags at once using the OR (|) operator:
1 2 |
std::cout.setf(std::ios::showpos | std::ios::uppercase); // turn on the std::ios::showpos and std::ios::uppercase flag std::cout << 27 << '\n'; |
To turn a flag off, use the unsetf() function:
1 2 3 4 |
std::cout.setf(std::ios::showpos); // turn on the std::ios::showpos flag std::cout << 27 << '\n'; std::cout.unsetf(std::ios::showpos); // turn off the std::ios::showpos flag std::cout << 28 << '\n'; |
This results in the following output:
+27 28
There’s one other bit of trickiness when using setf() that needs to be mentioned. Many flags belong to groups, called format groups. A format group is a group of flags that perform similar (sometimes mutually exclusive) formatting options. For example, a format group named “basefield” contains the flags “oct”, “dec”, and “hex”, which controls the base of integral values. By default, the “dec” flag is set. Consequently, if we do this:
1 2 |
std::cout.setf(std::ios::hex); // try to turn on hex output std::cout << 27 << '\n'; |
We get the following output:
27
It didn’t work! The reason why is because setf() only turns flags on -- it isn’t smart enough to turn mutually exclusive flags off. Consequently, when we turned std::hex on, std::ios::dec was still on, and std::ios::dec apparently takes precedence. There are two ways to get around this problem.
First, we can turn off std::ios::dec so that only std::hex is set:
1 2 3 |
std::cout.unsetf(std::ios::dec); // turn off decimal output std::cout.setf(std::ios::hex); // turn on hexadecimal output std::cout << 27 << '\n'; |
Now we get output as expected:
1b
The second way is to use a different form of setf() that takes two parameters: the first parameter is the flag to set, and the second is the formatting group it belongs to. When using this form of setf(), all of the flags belonging to the group are turned off, and only the flag passed in is turned on. For example:
1 2 3 |
// Turn on std::ios::hex as the only std::ios::basefield flag std::cout.setf(std::ios::hex, std::ios::basefield); std::cout << 27 << '\n'; |
This also produces the expected output:
1b
Using setf() and unsetf() tends to be awkward, so C++ provides a second way to change the formatting options: manipulators. The nice thing about manipulators is that they are smart enough to turn on and off the appropriate flags. Here is an example of using some manipulators to change the base:
1 2 3 |
std::cout << std::hex << 27 << '\n'; // print 27 in hex std::cout << 28 << '\n'; // we're still in hex std::cout << std::dec << 29 << '\n'; // back to decimal |
This program produces the output:
1b 1c 29
In general, using manipulators is much easier than setting and unsetting flags. Many options are available via both flags and manipulators (such as changing the base), however, other options are only available via flags or via manipulators, so it’s important to know how to use both.
Useful formatters
Here is a list of some of the more useful flags, manipulators, and member functions. Flags live in the std::ios class, manipulators live in the std namespace, and the member functions live in the std::ostream class.
Group | Flag | Meaning |
---|---|---|
std::ios::boolalpha | If set, booleans print “true” or “false”. If not set, booleans print 0 or 1 |
Manipulator | Meaning |
---|---|
std::boolalpha | Booleans print “true” or “false” |
std::noboolalpha | Booleans print 0 or 1 (default) |
Example:
1 2 3 4 5 6 7 8 |
std::cout << true << " " << false << '\n'; std::cout.setf(std::ios::boolalpha); std::cout << true << " " << false << '\n'; std::cout << std::noboolalpha << true << " " << false << '\n'; std::cout << std::boolalpha << true << " " << false << '\n'; |
Result:
1 0 true false 1 0 true false
Group | Flag | Meaning |
---|---|---|
std::ios::showpos | If set, prefix positive numbers with a + |
Manipulator | Meaning |
---|---|
std::showpos | Prefixes positive numbers with a + |
std::noshowpos | Doesn’t prefix positive numbers with a + |
Example:
1 2 3 4 5 6 7 8 |
std::cout << 5 << '\n'; std::cout.setf(std::ios::showpos); std::cout << 5 << '\n'; std::cout << std::noshowpos << 5 << '\n'; std::cout << std::showpos << 5 << '\n'; |
Result:
5 +5 5 +5
Group | Flag | Meaning |
---|---|---|
std::ios::uppercase | If set, uses upper case letters |
Manipulator | Meaning |
---|---|
std::uppercase | Uses upper case letters |
std::nouppercase | Uses lower case letters |
Example:
1 2 3 4 5 6 7 8 |
std::cout << 12345678.9 << '\n'; std::cout.setf(std::ios::uppercase); std::cout << 12345678.9 << '\n'; std::cout << std::nouppercase << 12345678.9 << '\n'; std::cout << std::uppercase << 12345678.9 << '\n'; |
Result:
1.23457e+007 1.23457E+007 1.23457e+007 1.23457E+007
Group | Flag | Meaning |
---|---|---|
std::ios::basefield | std::ios::dec | Prints values in decimal (default) |
std::ios::basefield | std::ios::hex | Prints values in hexadecimal |
std::ios::basefield | std::ios::oct | Prints values in octal |
std::ios::basefield | (none) | Prints values according to leading characters of value |
Manipulator | Meaning |
---|---|
std::dec | Prints values in decimal |
std::hex | Prints values in hexadecimal |
std::oct | Prints values in octal |
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
std::cout << 27 << '\n'; std::cout.setf(std::ios::dec, std::ios::basefield); std::cout << 27 << '\n'; std::cout.setf(std::ios::oct, std::ios::basefield); std::cout << 27 << '\n'; std::cout.setf(std::ios::hex, std::ios::basefield); std::cout << 27 << '\n'; std::cout << std::dec << 27 << '\n'; std::cout << std::oct << 27 << '\n'; std::cout << std::hex << 27 << '\n'; |
Result:
27 27 33 1b 27 33 1b
By now, you should be able to see the relationship between setting formatting via flag and via manipulators. In future examples, we will use manipulators unless they are not available.
Precision, notation, and decimal points
Using manipulators (or flags), it is possible to change the precision and format with which floating point numbers are displayed. There are several formatting options that combine in somewhat complex ways, so we will take a closer look at this.
Group | Flag | Meaning |
---|---|---|
std::ios::floatfield | std::ios::fixed | Uses decimal notation for floating-point numbers |
std::ios::floatfield | std::ios::scientific | Uses scientific notation for floating-point numbers |
std::ios::floatfield | (none) | Uses fixed for numbers with few digits, scientific otherwise |
std::ios::floatfield | std::ios::showpoint | Always show a decimal point and trailing 0’s for floating-point values |
Manipulator | Meaning |
---|---|
std::fixed | Use decimal notation for values |
std::scientific | Use scientific notation for values |
std::showpoint | Show a decimal point and trailing 0’s for floating-point values |
std::noshowpoint | Don’t show a decimal point and trailing 0’s for floating-point values |
std::setprecision(int) | Sets the precision of floating-point numbers (defined in iomanip.h) |
Member function | Meaning |
---|---|
std::precision() | Returns the current precision of floating-point numbers |
std::precision(int) | Sets the precision of floating-point numbers and returns old precision |
If fixed or scientific notation is used, precision determines how many decimal places in the fraction is displayed. Note that if the precision is less than the number of significant digits, the number will be rounded.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
std::cout << std::fixed << '\n'; std::cout << std::setprecision(3) << 123.456 << '\n'; std::cout << std::setprecision(4) << 123.456 << '\n'; std::cout << std::setprecision(5) << 123.456 << '\n'; std::cout << std::setprecision(6) << 123.456 << '\n'; std::cout << std::setprecision(7) << 123.456 << '\n'; std::cout << std::scientific << '\n'; std::cout << std::setprecision(3) << 123.456 << '\n'; std::cout << std::setprecision(4) << 123.456 << '\n'; std::cout << std::setprecision(5) << 123.456 << '\n'; std::cout << std::setprecision(6) << 123.456 << '\n'; std::cout << std::setprecision(7) << 123.456 << '\n'; |
Produces the result:
123.456 123.4560 123.45600 123.456000 123.4560000 1.235e+002 1.2346e+002 1.23456e+002 1.234560e+002 1.2345600e+002
If neither fixed nor scientific are being used, precision determines how many significant digits should be displayed. Again, if the precision is less than the number of significant digits, the number will be rounded.
1 2 3 4 5 |
std::cout << std::setprecision(3) << 123.456 << '\n'; std::cout << std::setprecision(4) << 123.456 << '\n'; std::cout << std::setprecision(5) << 123.456 << '\n'; std::cout << std::setprecision(6) << 123.456 << '\n'; std::cout << std::setprecision(7) << 123.456 << '\n'; |
Produces the following result:
123 123.5 123.46 123.456 123.456
Using the showpoint manipulator or flag, you can make the stream write a decimal point and trailing zeros.
1 2 3 4 5 6 |
std::cout << std::showpoint << '\n'; std::cout << std::setprecision(3) << 123.456 << '\n'; std::cout << std::setprecision(4) << 123.456 << '\n'; std::cout << std::setprecision(5) << 123.456 << '\n'; std::cout << std::setprecision(6) << 123.456 << '\n'; std::cout << std::setprecision(7) << 123.456 << '\n'; |
Produces the following result:
123. 123.5 123.46 123.456 123.4560
Here’s a summary table with some more examples:
Option | Precision | 12345.0 | 0.12345 |
---|---|---|---|
Normal | 3 | 1.23e+004 | 0.123 |
4 | 1.235e+004 | 0.1235 | |
5 | 12345 | 0.12345 | |
6 | 12345 | 0.12345 | |
Showpoint | 3 | 1.23e+004 | 0.123 |
4 | 1.235e+004 | 0.1235 | |
5 | 12345. | 0.12345 | |
6 | 12345.0 | 0.123450 | |
Fixed | 3 | 12345.000 | 0.123 |
4 | 12345.0000 | 0.1235 | |
5 | 12345.00000 | 0.12345 | |
6 | 12345.000000 | 0.123450 | |
Scientific | 3 | 1.235e+004 | 1.235e-001 |
4 | 1.2345e+004 | 1.2345e-001 | |
5 | 1.23450e+004 | 1.23450e-001 | |
6 | 1.234500e+004 | 1.234500e-001 |
Width, fill characters, and justification
Typically when you print numbers, the numbers are printed without any regard to the space around them. However, it is possible to left or right justify the printing of numbers. In order to do this, we have to first define a field width, which defines the number of output spaces a value will have. If the actual number printed is smaller than the field width, it will be left or right justified (as specified). If the actual number is larger than the field width, it will not be truncated -- it will overflow the field.
Group | Flag | Meaning |
---|---|---|
std::ios::adjustfield | std::ios::internal | Left-justifies the sign of the number, and right-justifies the value |
std::ios::adjustfield | std::ios::left | Left-justifies the sign and value |
std::ios::adjustfield | std::ios::right | Right-justifies the sign and value (default) |
Manipulator | Meaning |
---|---|
std::internal | Left-justifies the sign of the number, and right-justifies the value |
std::left | Left-justifies the sign and value |
std::right | Right-justifies the sign and value |
std::setfill(char) | Sets the parameter as the fill character (defined in iomanip.h) |
std::setw(int) | Sets the field width for input and output to the parameter (defined in iomanip.h) |
Member function | Meaning |
---|---|
std::fill() | Returns the current fill character |
std::fill(char) | Sets the fill character and returns the old fill character |
std::width() | Returns the current field width |
std::width(int) | Sets the current field width and returns old field width |
In order to use any of these formatters, we first have to set a field width. This can be done via the width(int) member function, or the setw() manipulator. Note that right justification is the default.
1 2 3 4 5 |
std::cout << -12345 << '\n'; // print default value with no field width std::cout << std::setw(10) << -12345 << '\n'; // print default with field width std::cout << std::setw(10) << left << -12345 << '\n'; // print left justified std::cout << std::setw(10) << right << -12345 << '\n'; // print right justified std::cout << std::setw(10) << internal << -12345 << '\n'; // print internally justified |
This produces the result:
-12345 -12345 -12345 -12345 - 12345
One thing to note is that setw() and width() only affect the next output statement. They are not persistent like some other flags/manipulators.
Now, let’s set a fill character and do the same example:
1 2 3 4 5 6 |
std::cout.fill('*'); std::cout << -12345 << '\n'; // print default value with no field width std::cout << std::setw(10) << -12345 << '\n'; // print default with field width std::cout << std::setw(10) << left << -12345 << '\n'; // print left justified std::cout << std::setw(10) << right << -12345 << '\n'; // print right justified std::cout << std::setw(10) << internal << -12345 << '\n'; // print internally justified |
This produces the output:
-12345 ****-12345 -12345**** ****-12345 -****12345
Note that all the blank spaces in the field have been filled up with the fill character.
The ostream class and iostream library contain other output functions, flags, and manipulators that may be useful, depending on what you need to do. As with the istream class, those topics are really more suited for a tutorial or book focusing on the standard library (such as the excellent book “The C++ Standard Template Library” by Nicolai M. Josuttis).
![]() |
![]() |
![]() |
Hello guys,
just wanted to point out that when using std::setw() one should use std::endl to print a new line. In my IDE (Visual Studio Community) the '\n' uses up a space which has been set by std::setw(). I'm not sure if it's an IDE or compiler related issue.
You guys rock, keep on rocking \m/
hi, authors, there is a typo
should be std::ios::hex
thankyou for offering such a good book for us to learn
`std::hex` is correct, see https://en.cppreference.com/w/cpp/io/manip/hex
Was there something in the lessons that made you think it should be `std::ios::hex`?
[codestd::iosshowpos[/code] There's a missing scope resolution here.
Thanks, fixed.
Also, under the "Useful formatters" heading, in the section on "boolalpha", Line 3 states
but I believe it should be
right? Also, the next one has the showpos flag in the table as "std::ios::iosshowpos". I think that's a typo with the extraneous "ios" in front of "showpos", as in the code example you simply use "std::ios::showpos" for the flag.
Correct on both counts. Fixed. Thank you much for pointing these out.
Hi Alex,
I'm getting below error when i use "std::cout.setf(std::hex);".
error: no matching function for call to ‘std::basic_ostream<char>::unsetf(std::ios_base& (&)(std::ios_base&))’
std::cout.unsetf(std::hex);
and it gets resolved after i change it to "std::cout.setf(std::ios::hex);"
Yes, it should be as you suggest. I updated the lesson to include the correct ::ios prefixes.
Alex,
On Mac (macOS 10.12), many of the examples do not work as written here, so I'm including code that does work for all of the examples.
When using std::cout.setf (), values are not in the std:: namespace, but rather in the std::ios:: namespace:
boolalpha and noboolalpha are in the std:: namespace, and using std::setf () requires the std::ios:: namespace:
Again, the use of std:: vs. std::ios:: namespaces:
Again:
Again:
This one didn't require modifications within the code to work, but, it does require inclusion of the iomanip.h header. Also, I thought the first output of an extra '\n' isn't needed, so I took that out:
Again, the iomanip.h header is required, but the rest of this code was good to go, as is:
Again, the iomanip.h header is required, but the rest of this code was good to go, as is:
Again, the iomanip.h header is required, but the rest of this code was good to go, as is:
Thanks, Lamont. I'm on Windows 10 and was also having this issue.
Thanks for this.
Hello Alex, just a quick question regarding manipulators. Why would we type this:
using namespace std;
cout << hex << 27 << '\n'; //1b
cout << 28 << '\n'; //still in hexadecimal - 1c
cout << dec << 29 << '\n'; //back to dec - 29
as appose to this:
using namespace std;
cout << ios::hex << 27 << '\n'; //1b
cout << 28 << '\n'; //still in hexadecimal - 1c
cout << ios::dec << 29 << '\n'; //back to dec - 29
Including ios:: more or less breaks the code, but why does this occur?
Thanks
Because the article was wrong, and it should be std::hex and std::dec. I've updated the article. My apologies for the mistake.
Alright, cheers
shouldn't true be 1 and false be 0?
Why in the boolalpha, 0 is true?
Or was it a typo?
Typo. I've fixed it now.
Under "Useful formatters", second sentence, you wrote:
" manipulators lives in the std namespace".
I think "lives" should be singular.
In the section "Usefull Formaters", the "Group" column is empty on each flag table that has only one row. Is it normal?
Yup, those don't have a group.
For fun I had a go at writing a function that can format a double type to a specified number of significant figures returning the value as a string. It can display numbers in scientific format if that number is either less than some predefined value or greater than some other predefined value. Also you can set a "threshold-to-zero" value such that if the number is less than or equal to this threshold the string representation of the number is set to zero.
FormatOutput.h
FormatOutput.cpp
Note that should a rounded value overflow to the next decimal unit an extra significant figure is given. For example, using this function to round 999.95 to 4 s.f. results in a string containing "1000.0", whereas 999.94 results in the string "999.9", and 1000.04 gives "1000".
Hi Alex,
I think you made a mistake here by assigning showpoint flag to the floatfield group, since i,ve found (http://www.cplusplus.com/reference/ios/ios_base/setf/) that it belongs to the so called independent format flags. That's i think why this code doesn't perform properly:
#include <iostream>
#include <iomanip>
using namespace std;
int main ()
{
cout.setf(ios_base::showpoint,ios::floatfield);
cout << setprecision(4) << 831.0 << ' ' << 8e4;
}
It prints:831 8e+04. But as soon as I remove ios::floatfield from parameter list it performs as intended:831.0 8.000e+04 .
"uppercase - Uses upper case letters"
Who uses uppercase letters when this flag/manipulator is applied on streams. The program itself ?
std::cout does. When the program sends the uppercase manipulator to std::cout, std::cout will print upper case letters for the floating point exponent or hexadecimal values instead of lower case ones.
Hi Alex,
I think the uppercase examples are not correct. They are actually examples for setprecisions
No, it's correct. Using the uppercase manipulator makes std::cout print an uppercase E for the exponent of floating point numbers, as well as uppercase letters when printing hexadecimal values.
exactly it should be like:
0 1 –> should be 1 0
true false
0 1 –> should be 1 0
true false
Excellent Tutorial.............
Great tutorials. I've read them all so far.
However, at the boolalpha example on this page I noticed 0 represents true and 1 represents false?
0 1 --> should be 1 0
true false
0 1 --> should be 1 0
true false
I ran the example code to be sure (my world would collapse if true was 0 :P).
correct
Looking forward to see sections on vector, map, iterators, etc... There are many available sources online but I know when Alex write it it will be the best
Excellent Site. I am setting a book mark. I tried your examples and everything works fine. I would also like to reset the floating point precision back to its default. I am writing a library routine. I don't know what the user will have for their default precision but it would be great to capture it, change the precision to my own, then reset it back.
Thanks,
Vinny
So, how do you go about adjusting the size of the exponent from 3 digits to 2? I have a floating point number that I want outputted as 0.000E+00 instead of 0.000E+000.
Any ideas?
Thanks
I'm not sure you can adjust that in scientific notation format. If there is a way I'm not aware how.
I was stuck with the same problem. From the info i've gathered, the number of digits displayed in the exponent in scientific notation is implementation dependent, meaning it depends on the machine you are using.
Hi Alex,
It seems to me that the outputting of numbers with iostream is the worst part of C++ (and it's not even part of C++!) The thing that really bugs me is the persistance of things like floatfield and the non-persistance of the width settings. It means that for any given output statement you've no idea what will be displayed unless you explicitly set everything. For example, setting output to scientific somewhere in your program means that all subsequent output will be scientific unless you explicitly say otherwise - the only way I can see to get back to the default output is to use
std::cout.unsetf(std::ios::scientific|std::ios::showpoint|std::ios::fixed);
Bring on C# (or use stdio) I say.
Anyway enough of that, there are a few typos on this page:
In the description of the floatfield group, "floatfield" is missing for showpoint.
In the floating point output examples table, for "fixed" precision 3 there are two decimal points, and for "scientific" precisions 4-6 there are no decimal points.
VS 2005 seems to have a bug regarding showpoint manipulator. The following code:
double x = 1.2345;
cout << showpoint << x << endl;
cout << scientific << x << endl;
cout << showpoint << x << endl;
cout.setf(std::ios::showpoint,std::ios::floatfield);
cout << x << endl;
produces:
1.23450
1.234500e+000
1.234500e+000
1.23450
so you need to use setf to switch from scientific to showpoint (not that I can imagine that will worry too many people!)
I am personally not a fan of the C++ I/O operators for outputting formatted numbers. In those cases, I usually fall back to the old C-style stdio printf() function way of doing things. Thanks for noting the errors.