Stream Manipulators

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 reset basefield to 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:

skipws

Skip whitespace on input stream

noskipws

Do not skip whitespace

left

Left justify output in a field

right

right justify output in a field

internal

Left pad number signs in a field, and right pad number magnitudes

dec

Treat integers as decimal

oct

Treat integers as octal

hex

Treat integers as hexadecimal

showbase

Output the base of a number in front of the number (0 for octal, 0x or 0X for hexadecimal)

noshowbase

Do not output the base of the number

showpoint

Output floating point numbers with a decimal point

noshowpoint

Do not output floating point numbers with a decimal point

uppercase

Use uppercase letters for hex integers and scientific notation

nouppercase

Do not use uppercase letters for hex integers and scientific notation

showpos

Precede positive numbers with a + sign

noshowpos

Do not precede positive numbers with a = sign

scientific

Output floating point values in scientific notation

fixed

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() const returns 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() const returns the current value of the format settings
  • fmtflags 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

fmtflags is 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
Index