Output Formatting

Programming Workshop 2 (CSCI 1061U)

Faisal Qureshi

Faculty of Science, UOIT

http://vclab.science.uoit.ca


C++ provides a number of facilities to control how output sent to console or output file streams is formatted. We can use these to modify the behavior of cout.

You'll need to include iomanip header file to make use of these.

setw

setw sets the minimum field width for the value to be printed. setw only effects the next value to be printed.

setw.cpp

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
  cout << "no setw" << endl;
  cout << '*' << 2 << '*'<< endl;
  
  cout << '*' << "setw 10" << endl;
  cout << '*' << setw(10) << 2 << '*'<< endl;

  cout << '*' << "setw 20" << endl;
  cout << '*' << setw(20) << 2 << '*'<< endl;

  cout << '*' << "setw 0" << endl;
  cout << '*' << setw(0) << 2 << '*'<< endl;

  return 0;
}

Output

no setw
*2*
*setw 10
*         2*
*setw 20
*                   2*
*setw 0
*2*

Justification using left, right and internal

justify.cpp

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
  cout << "1" << endl;
  cout << "*" << -23 << "*" << endl;
  cout << "*" << setw(6) << -23 << "*" << endl;

  cout << "2" << endl;
  cout << left;
  cout << "*" << setw(6) << -23 << "*" << endl;

  cout << "3" << endl;
  cout << internal;
  cout << "*" << setw(6) << -23 << "*" << endl;
  
  cout << "4" << endl;
  cout << right;
  cout << "*" << setw(6) << -23 << "*" << endl;

  cout << "5" << endl;
  cout << internal;
  cout << "*" << setw(6) << -23 << "*" << endl;
  
  return 0;
}

Output

1
*-23*
*   -23*
2
*-23   *
3
*-   23*
4
*   -23*
5
*-   23*

boolalpha and noboolapha

By default Boolean values are printed as either 0 or 1. We can, however, choose to instead print them as false or true.

boolalpha.cpp

// noboolalpha and boolalpha

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
  bool a = true, b = false;

  cout << "a " << a << endl;
  cout << boolalpha <<  "a " << a << endl;

  cout << noboolalpha << "b " << b << endl;
  cout << boolalpha <<  "b " << b << endl;


  return 0;
}

Output

a 1
a true
b 0
b false

Printing numbers in decimal, octal or hexadecimal notations

Octal and hexadecimal notations are often used to represent numbers in computers.

A bit about notations

Decimal notation

We all know decimal notation. It comprises of 10 symbols: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.

A single digit decimal number can represent up to 10 values. An \(n\) digit binary number can represent up to \(10^n\) values.

Binary notation

Uses two symbols: 0 and 1.

A single digit binary number can represent up to 2 values. An \(n\) digit binary number can represent up to \(2^n\) values.

Octal notation

Octal notation comprises of 8 symbols: 0, 1, 2, 3, 4, 5, 6, 7. Any symbol in octal notation can be expressed using 3 bits as seen below.

Octal Binary
0 000
1 001
2 010
3 011
4 100
5 101
6 110
7 111

A single digit octal number can represent up to 8 values. An \(n\) digit octal number can represent up to \(8^n\) values.

Hexadecimal notation

Octal notation comprises of 16 symbols: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. Any symbol in hexadecimal notation can be expressed using 4 bits as seen below.

Hexadecimal Binary
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
A 1010
B 1011
C 1100
D 1101
E 1110
F 1111

A single digit hexadecimal number can represent up to 16 values. An \(n\) digit hexadecimal number can represent up to \(16^n\) values.

Hexadecimal notation is often used to display bit patterns stored in a byte. Say letter A is stored in a byte. We know that ASCII code for letter A is 65. The binary value is 01000001. Binary values are difficult to parse. It is often easier to represent it using hexadecimal notation. Note that each hexadecimal symbol takes 4 bits, so to represent 8 bits, we will use two hexadecimal symbols. Specifically, 01000001 can be conveniently written as 41 in hexadecimal notation.

dec, oct and hex modifiers

You can use dec, oct and hex modifiers to display numbers in decimal, octal or hexadecimal notation. Furthermore, you can use showbase modifier to also indicate if the number is using decimal, octal or hexadecimal notation.

Consider a number 65. Unless someone tell me, I wouldn't know if it is using decimal, octal or hexadecimal notation. In C++, we use the following convention to indicate whether a number is decimal, octal or hexadecimal.

bases.cpp

// showbase and noshowbase --- identifies decimal, octal and hexadecimal numbers.


#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
  int a = 234532;

  cout << "a (decimal) " << dec << a << endl;
  cout << "a (octal) " << oct << a << endl;
  cout << "a (hex) " << hex << a << endl;

  cout << "With showbase" << endl;
  cout << showbase;
  cout << "a (decimal) " << dec << a << endl;
  cout << "a (octal) " << oct << a << endl;
  cout << "a (hex) " << hex << a << endl;

  cout << "With noshowbase" << endl;
  cout << noshowbase;
  cout << "a (decimal) " << dec << a << endl;
  cout << "a (octal) " << oct << a << endl;
  cout << "a (hex) " << hex << a << endl;


  return 0;
}

Output

a (decimal) 234532
a (octal) 712044
a (hex) 39424
With showbase
a (decimal) 234532
a (octal) 0712044
a (hex) 0x39424
With noshowbase
a (decimal) 234532
a (octal) 712044
a (hex) 39424

uppercase and nouppercase

These modifiers can be used to modify how hexadecimal numbers are displayed. These also effect numbers displayed using scientific notation.

case.cpp

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
  int a = 234532339;
  float b = 32000004032400.34;

  cout << showbase << hex;
  cout << "a (hex) " << a << endl;
  cout << uppercase;
  cout << "a (hex) " << a << endl;

  cout << nouppercase << dec;
  cout << "b (hex) " << b << endl;
  cout << uppercase;
  cout << "b (hex) " << b << endl;
  
  return 0;
}

Output

a (hex) 0xdfaadf3
a (hex) 0XDFAADF3
b (hex) 3.2e+13
b (hex) 3.2E+13

showpos and noshowpos

Use showpos and noshowpos to print + next to a positive number.

showpos.cpp

// noshowpos and showpos --- prints a + sign next to a positive number

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
  int a = 5, b = -6;
  float c = 3.4, d = -35.6;

  cout << "a " << a << endl;
  cout << "b " << b << endl;
  cout << "c " << c << endl;
  cout << "d " << d << endl;

  cout << showpos;
  cout << "a " << a << endl;
  cout << "b " << b << endl;
  cout << "c " << c << endl;
  cout << "d " << d << endl;

  
  return 0;
}

Output

a 5
b -6
c 3.4
d -35.6
a +5
b -6
c +3.4
d -35.6

Floating point numbers

Floats can be displayed using general, fixed or scientific format. The default is general, which automatically picks fixed or scientific based upon what yields a more "pleasant" result. For example, for 5.2, it is better to use the fixed format; however, 32000004032400.34 looks better in scientific format.

Once you pick fixed or scientific format, there is no easy way to rever to general format. You will have to use

cout.unsetf(ios::fixed | ios::scientific);

to revert to general format.

setprecision is used to specify roughly the number of digits displayed for the number. In general format, the setprecision specifies the maximum number of digits displayed. This includes digits before and after the decimal point, excluding the decimal point. In fixed and scientific formats, the precision specifies the number of digits after the decimal point.

showpoint modifier can be used to display the trailing zeros.

floats.cpp

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
  float a = 5.2;
  float b = 32000004032400.34;

  cout << "Different formats" << endl;
  cout << "General" << endl;
  cout << a << " " << b << endl;
  cout << "Fixed" << endl;
  cout << fixed << a << " " << b << endl;
  cout << "Scientific" << endl;
  cout << scientific << a << " " << b << endl;

  cout << "Back to general" << endl;
  cout.unsetf(ios::fixed | ios::scientific);
  cout << a << " " << b << endl;

  cout << "Set precision to 1" << endl;
  cout << setprecision(1) << a << " " << b << endl;

  cout << "Set precision to 20" << endl;
  cout << setprecision(20) << a << " " << b << endl;

  cout << "showpoint" << endl;
  cout << setprecision(6) << showpoint << a << endl;
  
  return 0;
}

Output

Different formats
General
5.2 3.2e+13
Fixed
5.200000 32000004063232.000000
Scientific
5.200000e+00 3.200000e+13
Back to general
5.2 3.2e+13
Set precision to 1
5 3e+13
Set precision to 20
5.1999998092651367188 32000004063232
showpoint
5.20000

setfill

The default fill character is a space ' '. This is the character that is appended (or prepended) to the value when setw is used to set the width. We can change this character using setfill command.

fill.cpp

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    cout << "default fill: " << setw(10) << 42 << endl;
    cout << "setfill('*'): " << setfill('*');
    cout << setw(10) << 42 << endl;
}

Output

default fill:         42
setfill('*'): ********42

References