Stream Manipulators
Stream manipulators perform formatting tasks. They can:
- set the base for a field
- set the precision for a floating point field
- set field width
- set precision
- set and unset format flags
- set the fill character for fields
- insert a newline and flush an output stream
- flush an output stream
- insert a null terminator
- skip whitespace in an input stream
- etc…
Integer Base
You can use the dec, oct, hex and setbase stream manipulators to control how integers are interpreted for a stream:
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
#include <iomanip>
int main(int argc, const char * argv[])
{
int n;
std::cout << "Enter a decimal number: ";
std::cin >> n;
std::cout << n << " in hexadecimal is: "
<< std::hex << n << std::endl
<< std::dec << n
<< " in octal is: "
<< std::oct << n << std::endl
<< std::setbase(8) << n << "(octal) "
<< "in decimal is: "
<< std::dec << n << std::endl;
return 0;
}which outputs:
Enter a decimal number: 19
19 in hexadecimal is: 13
19 in octal is: 23
23(octal) in decimal is: 19
Program ended with exit code: 0
NOTE: The italicized number is input to the program.
For
setbase(base), values of base other than 8, 10, or 16 resetbasefieldto zero, which corresponds to decimal output and prefix-dependent input.
Floating Point Precision
std::ios_base& fixed( std::ios_base& str )
Sets the floatfield of the stream str to fixed (fixed floating point notation).
setprecision(streamsize precision), precision(streamsize, precision)
The precision member function of ios_base, and the setprecision stream manipulator control the precision of floating point numbers:
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
#include <iomanip>
int main(int argc, const char * argv[])
{
const double PI = 3.1415927;
int i;
std::cout << std::fixed; // use floating point fixed notation
for (i = 0; i < 6; i++)
{
std::cout.precision(i);
std::cout << PI << std::endl;
}
std::cout << std::endl;
for (i = 0; i < 6; i++)
{
std::cout << std::setprecision(i) << PI << std::endl;
}
return 0;
}which outputs:
3
3.1
3.14
3.142
3.1416
3.14159
3
3.1
3.14
3.142
3.1416
3.14159
Program ended with exit code: 0
Field Width
width(), setw()
The width member function and the setw stream manipulator set the minimum width for the next field only.
If the data is larger than the specified width, it overflows the width:
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
#include <iomanip>
int main(int argc, const char * argv[])
{
char string[] = "Hi!";
for (int w = 0; w < 6; w++)
{
std::cout << w << ": <";
std::cout.width(w);
std::cout << string << ">" << std::endl;
}
for (int w = 0; w < 6; w++)
{
std::cout << w << ": <"
<< std::setw(w)
<< string << ">" << std::endl;
}
return 0;
}which outputs:
0: <Hi!>
1: <Hi!>
2: <Hi!>
3: <Hi!>
4: < Hi!>
5: < Hi!>
0: <Hi!>
1: <Hi!>
2: <Hi!>
3: <Hi!>
4: < Hi!>
5: < Hi!>
Program ended with exit code: 0
width and setw both also work on input streams:
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
#include <iomanip>
int main(int argc, const char * argv[])
{
char buffer[8];
int w = 2;
std::cout << "Enter a line of text, a newline, and then EOF:" << std::endl;
std::cin.width(w);
while ( std::cin >> buffer )
{
std::cout << '<' << buffer << '>' << std::endl;
if ( w < sizeof(buffer) ) // Don't overflow buffer
{
std::cin.width(++w);
std::cin.width(++w);
}
}
return 0;
}which outputs:
Enter a line of text, a newline, and then EOF:
Omnia Gallia in tres partes divisa est.
<O>
<mni>
<a>
<Gallia>
<in>
<tres>
<partes>
<divisa>
<est.>
Program ended with exit code: 0
Stream Format States
Here is a table of available stream manipulators for formatting fields:
|
Skip whitespace on input stream |
|
Do not skip whitespace |
|
Left justify output in a field |
|
right justify output in a field |
|
Left pad number signs in a field, and right pad number magnitudes |
|
Treat integers as decimal |
|
Treat integers as octal |
|
Treat integers as hexadecimal |
|
Output the base of a number in front of the number (0 for octal, 0x or 0X for hexadecimal) |
|
Do not output the base of the number |
|
Output floating point numbers with a decimal point |
|
Do not output floating point numbers with a decimal point |
|
Use uppercase letters for hex integers and scientific notation |
|
Do not use uppercase letters for hex integers and scientific notation |
|
Precede positive numbers with a + sign |
|
Do not precede positive numbers with a = sign |
|
Output floating point values in scientific notation |
|
Ouput floating point values in fixed point notation |
Trailing Zeros, Decimal Points, and Justification
An example program that uses some of these manipulators:
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
#include <iomanip>
void output(int i, double d, char s[])
{
std::cout << "<" << std::setw(10) << i << "> "
<< "<" << std::setw(10) << d << "> "
<< "<" << std::setw(10) << s << ">"
<< std::endl;
}
int main(int argc, const char * argv[])
{
std::cout << "12.0000 displays as <" << 12.0000 << ">" << std::endl
<< "12.1000 displays as <" << 12.1000 << ">" << std::endl;
std::cout << std::endl;
std::cout << std::showpoint;
std::cout << "12.0000 displays as <" << 12.0000 << ">" << std::endl
<< "12.1000 displays as <" << 12.1000 << ">" << std::endl;
std::cout << std::endl;
int i = -12345;
double d = -17.56;
char s[] = "Hello";
std::cout << "The default is to right justify:" << std::endl;
output(i, d, s);
std::cout << std::endl;
std::cout << "Set left justification:" << std::endl;
std::cout << std::left;
output(i, d, s);
std::cout << std::endl;
std::cout << "Set internal justification:" << std::endl;
std::cout << std::internal;
output(i, d, s);
std::cout << std::endl;
std::cout << "showbase + showpos with internal justification:" << std::endl;
int v = 1234;
std::cout << std::showbase << std::showpos;
std::cout << "<" << std::setw(10) << std::dec << v << "> "
<< "<" << std::setw(10) << std::oct << v << "> "
<< "<" << std::setw(10) << std::hex << v << ">" << std::endl;
return 0;
}which outputs:
12.0000 displays as <12>
12.1000 displays as <12.1>
12.0000 displays as <12.0000>
12.1000 displays as <12.1000>
The default is to right justify:
< -12345> < -17.5600> < Hello>
Set left justification:
<-12345 > <-17.5600 > <Hello >
Set internal justification:
<- 12345> <- 17.5600> < Hello>
showbase + showpos with internal justification:
<+ 1234> < 02322> <0x 4d2>
Program ended with exit code: 0
Fill Characters
Fill (or padding) characters are used with adjusted fields. The default fill character is space.
The char fill() const member function returns the current fill character
The char fill(char cfill) member function sets the fill character and returns the previous fill character.
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
#include <iomanip>
int main(int argc, const char * argv[])
{
int i = 200;
std::cout << std::showbase;
std::cout.fill('$');
std::cout << "<" << std::setw(10) << i << ">" << std::endl;
std::cout.fill('#');
std::cout << std::left << "<" << std::setw(10) << "Bye!" << ">" << std::endl;
std::cout << std::internal << std::setfill('^')
<< "<" << std::setw(10) << std::hex << i << ">" << std::endl;
return 0;
}which outputs:
<$$$$$$$200>
<Bye!######>
<0x^^^^^^c8>
Program ended with exit code: 0
Scientific and Fixed Point Formats
The scientific and fixed manipulators control the output format of floating point numbers.
There are three floating point formats:
- Default (‘general’ or ‘automatic’) format
- Scientific format
- Fixed format
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
int main(int argc, const char * argv[])
{
double x = .001234567;
double y = 1.946e9;
// Default format:
std::cout << "<" << x << "> <" << y << ">" << std::endl;
// Scientific format:
std::cout << std::scientific;
std::cout << "<" << x << "> <" << y << ">" << std::endl;
// Fixed format:
std::cout << std::fixed;
std::cout << "<" << x << "> <" << y << ">" << std::endl;
// Default format:
std::cout.unsetf(std::ios_base::fixed);
std::cout << "<" << x << "> <" << y << ">" << std::endl;
return 0;
}which outputs:
<0.00123457> <1.946e+09>
<1.234567e-03> <1.946000e+09>
<0.001235> <1946000000.000000>
<0.00123457> <1.946e+09>
Program ended with exit code: 0
Precision
Precision means different things in different floating point format modes:
- In default mode, precision denotes the total number of significant digits.
- In fixed and scientific modes, precision denotes the number of digits after the decimal point.
The default precision is 6.
The precision member function and setprecision stream manipulator control the precision for floating point numbers in a stream:
int precision() constreturns the current precision setting.int precision(int newPrec)sets a new precision, and returns the previous precision value.
For example, for the default format:
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
int main(int argc, const char * argv[])
{
double value = 4321.123456789;
for (int places = 0; places < 10; places++)
{
std::cout.precision(places);
std::cout << places << ":" << value << std::endl;
}
return 0;
}which outputs:
0:4e+03
1:4e+03
2:4.3e+03
3:4.32e+03
4:4321
5:4321.1
6:4321.12
7:4321.123
8:4321.1235
9:4321.12346
Program ended with exit code: 0
Which shows that the precision means the total number of significant digits, and that the value will overflow if it can’t be represented in the specified number of digits.
For the scientific format:
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
int main(int argc, const char * argv[])
{
double value = 4321.123456789;
std::cout << std::scientific;
for (int places = 0; places < 10; places++)
{
std::cout.precision(places);
std::cout << places << ":" << value << std::endl;
}
return 0;
}which outputs:
0:4e+03
1:4.3e+03
2:4.32e+03
3:4.321e+03
4:4.3211e+03
5:4.32112e+03
6:4.321123e+03
7:4.3211235e+03
8:4.32112346e+03
9:4.321123457e+03
Program ended with exit code: 0
Which shows that, in scientific format, precision means the number of digits after the decimal point.
And for the fixed format, using the setprecision stream manipulator:
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
#include <iomanip>
int main(int argc, const char * argv[])
{
double value = 4321.123456789;
std::cout << std::fixed;
for (int places = 0; places < 10; places++)
{
std::cout << std::setprecision(places)
<< places << ":" << value << std::endl;
}
return 0;
}which outputs:
0:4321
1:4321.1
2:4321.12
3:4321.123
4:4321.1235
5:4321.12346
6:4321.123457
7:4321.1234568
8:4321.12345679
9:4321.123456789
Program ended with exit code: 0
Which shows that, in fixed format, precision means the number of digits after the decimal point.
Upper/Lowercase
The uppercase stream manipulator forces:
- For hexadecimal integers, upper case hex letters and upper case X in the hex indicator
- For scientific format floating point, upper case E in the exponent indicator
The nouppercase stream manipulator resets this.
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
#include <iomanip>
int main(int argc, const char * argv[])
{
double value = 4321.12345678;
int i = 3000;
std::cout << std::scientific << std::showbase
<< "<" << value << "> <" << std::hex << i << ">" << std::endl;
std::cout << std::uppercase
<< "<" << value << "> <" << std::hex << i << ">" << std::endl;
std::cout << std::nouppercase
<< "<" << value << "> <" << std::hex << i << ">" << std::endl;
return 0;
}which outputs:
<4.321123e+03> <0xbb8>
<4.321123E+03> <0XBB8>
<4.321123e+03> <0xbb8>
Program ended with exit code: 0
Boolean Format
Normally, boolean values output as 0 or 1.
The stream manipulator boolalpha causes boolean values to display as true or false
The stream manipulator noboolalpha resets this.
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
#include <iomanip>
int main(int argc, const char * argv[])
{
bool value = true;
std::cout << value << " (NOT " << !value << ")" << std::endl;
std::cout << std::boolalpha
<< value << " (NOT " << !value << ")" << std::endl;
return 0;
}which outputs:
1 (NOT 0)
true (NOT false)
Program ended with exit code: 0
fmtflags and flags
An output stream’s format status is maintained in a data type fmtflags.
Member function flags can be used to determine or reset the fmtflags values.
fmtflags flags() constreturns the current value of the format settingsfmtflags flags(fmtflags fmtfl)sets the format state and returns the prior settings.
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
void output(int i, double d)
{
std::cout << "Flags = " << std::cout.flags() << std::endl
<< i << "\t" << d << std::endl;
}
int main(int argc, const char * argv[])
{
int i = 4523;
double d = 0.0987654321;
// Output default flags and values
output(i, d);
// Save old format flags
std::ios_base::fmtflags oldFormat = std::cout.flags();
// Set some formats
std::cout << std::showbase << std::hex << std::fixed;
// Output new flags and values
output(i, d);
// Restore old format flags
std::cout.flags(oldFormat);
// Output flags and values again
output(i, d);
return 0;
}which outputs:
Flags = 4098
4523 0.0987654
Flags = 0x120c
0x11ab 0.098765
Flags = 4098
4523 0.0987654
Program ended with exit code: 0
fmtflagsis implementation-defined.
Stream Error States
You can test whether a stream operation succeeded or failed using the idiom:
while (cin >> name)
{
// …
}
or:
while (true)
{
// …
if (!(cin >> name))
break;
// …
}
You can also test the state of the stream via the stream error state.
Use access member functions:
eof() — end of file (stream) seen
fail() — next operation will fail
bad() — stream corrupted
good() — next operation may succeed
rdstate() — read all stream state bits
clear(int mask = 0) — clear or set state bits
“Applying an input operation to a stream that is not in the good() state is a null operation.”
For example:
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
void output(const std::string &text)
{
std::cout << text << std::endl
<< "rdstate(): " << std::cin.rdstate() << std::endl
<< " eof(): " << std::cin.eof() << std::endl
<< " fail(): " << std::cin.fail() << std::endl
<< " bad(): " << std::cin.bad() << std::endl
<< " good(): " << std::cin.good() << std::endl;
}
int main(int argc, const char * argv[])
{
int i;
output("Before input:");
std::cout << "Enter something that "
<< "is not an integer: ";
std::cin >> i;
std::cout << std::endl;
output("After input:");
std::cin.clear(); // Clear stream
output("After clearing stream:");
return 0;
}which outputs:
Before input:
rdstate(): 0
eof(): 0
fail(): 0
bad(): 0
good(): 1
Enter something that is not an integer: x
After input:
rdstate(): 4
eof(): 0
fail(): 1
bad(): 0
good(): 0
After clearing stream:
rdstate(): 0
eof(): 0
fail(): 0
bad(): 0
good(): 1
Program ended with exit code: 0
You can also test for individual bits:
eofbit — set for a stream when end-of-file encountered
failbit — set for a stream when a format error occurs
badbit — set for a stream when an error occurs that results in loss of data (generally unrecoverable)
goodbit — set for a stream when none of the bits eofbit, failbit or badbit is set.
//
// main.cpp
// iostreams - Stream Manipulators
//
// Created by Bryan Higgs on 9/2/24.
//
#include <iostream>
void output(const std::string &text)
{
std::cout << text << std::endl;
std::ios_base::iostate state = std::cin.rdstate();
if (state & std::ios_base::eofbit)
std::cout << "eof bit set" << std::endl;
if (state & std::ios_base::failbit)
std::cout << "fail bit set" << std::endl;
if (state & std::ios_base::badbit)
std::cout << "bad bit set" << std::endl;
if (state & std::ios_base::goodbit)
std::cout << "good bit set" << std::endl;
}
int main(int argc, const char * argv[])
{
int i;
output("Before input:");
std::cout << "Enter something that is not an integer: ";
std::cin >> i;
std::cout << std::endl;
output("After input:");
std::cin.clear(); // Clear stream
output("After clearing stream:");
return 0;
}which outputs:
Before input:
Enter something that is not an integer: x
After input:
fail bit set
After clearing stream:
Program ended with exit code: 0