Overview of Formatted Input/Output

Overview of Formatted Output

The input and output facilities provided by cout and cin are both simple and powerful. You will NOT learn these functions by reading and taking notes alone. You MUST practice with examples on your own. Also, there are many different ways to format output. If you are interested in finding out, then YOU must experiment with them. (I'm not going to play the what if... game.)

Basics: To use cout, you must include the appropriate header file:
#include <iostream> // No .h extension
The iostream header actually contains definitions for two types: istream and ostream. The stream objects use special operators to perform their "magic". The ostream object uses the insertion operator (you are inserting values into the stream) or casually called the output operator:
std::cout << 15;    // output the integer 15
std::cout << 3.14;  // output the double 3.14
std::cout << "foo"; // output the NUL terminated string foo
Output:
153.14foo
Broken down into its parts (tokens):
namespace   scope-resolution-operator   object   insertion-operator   value   statement-terminator
   std               ::                  cout           <<             15             ;
You can chain the operations together in a single statement:
  // All in one statement
std::cout << 15 << 3.14 << "foo";
Obvious questions:

Comparing printf with cout

Given these three variables:
int i = 42;
float f = 1.23456789F;
double d = 3.1415926535897932384626433832795;
Using the defaults:
printfcout
printf("i is |%i|\n", i);
printf("f is |%f|\n", f);
printf("d is |%f|\n", d);

Output:
i is |42|
f is |1.234568|
d is |3.141593|
std::cout << "i is |" << i << "|" << std::endl;
std::cout << "f is |" << f << "|" << std::endl;
std::cout << "d is |" << d << "|" << std::endl;

Output:
i is |42|
f is |1.23457|
d is |3.14159|
When printing floating-point values:

Technical Note: There is a minor difference between std::endl and using the newline character: (\n). Using std::endl will flush the buffer after printing the newline. Using just the newline won't. Flushing the buffer guarantees that all characters will be output, regardless of whether or not the program crashes. There is a performance issue when flushing every write. However, if you're writing to the screen, then you already don't care about performance. (The performance will be more about the speed of the video than any flushing that might occur.) In non-interactive situations (read: writing to a file), there may be a need to suppress any unnecessary flushing.

Changing the default precision

Use the precision member to change the number of significant digits displayed for floating-point values. All of the subsequent floating-point values will be displayed to value significant digits.
cout.precision(value);
Notice that precision appears to be a member of the cout object (structure) and that precision also appears to be a function! What's going on here?

Example:

float f = 123.4567F;
double d = 3.1415926535897932384626433832795;

  // Modified precision (3, 6, 9, etc.)
for (int i = 3; i <= 15; i += 3)
{
  std::cout << "precision is " << i << std::endl;
  std::cout.precision(i);
  std::cout << "f is |" << f << "|" << std::endl;
  std::cout << "d is |" << d << "|" << std::endl;
  std::cout << std::endl;
}
Output:
precision is 3
f is |123|
d is |3.14|

precision is 6
f is |123.457|
d is |3.14159|

precision is 9
f is |123.456703|
d is |3.14159265|

precision is 12
f is |123.456703186|
d is |3.14159265359|

precision is 15
f is |123.456703186035|
d is |3.14159265358979|
Remember that a float has only 6 decimal digits of precision and a double has only 15 decimal digits of precision.

With printf, the value after the decimal point (e.g. %8.5f) was the precision.

Changing the field width

Use the width member of the cout object to modify the width:
cout.width(value);
The next value displayed will require at least value characters in the output. (Like printf, if the size of value is smaller than the number of characters required to display the value, the output will not be truncated.)

Unlike precision, the new width specification will only be applied to the next output operation before being reset. (Meaning that it will only apply to one << operation.)

Default right justified:
int i = 42;
float f = 1.23456789F;
double d = 3.141592653589793238426433832795;
printfcout
  // Set the width (default right justified)
printf("i is |%12i|\n", i);
printf("f is |%12f|\n", f);
printf("d is |%12f|\n", d);
printf("\n");

Output: (spaces are shown with a ·)
i is |··········42|
f is |····1.234568|
d is |····3.141593|
  // Set the width (default right justified)
std::cout << "i is |";
std::cout.width(12);
std::cout << i << "|" << std::endl;

std::cout << "f is |";
std::cout.width(12);
std::cout << f << "|" << std::endl;

std::cout << "d is |";
std::cout.width(12);
std::cout << d << "|" << std::endl;

Output: (spaces are shown with a ·)
i is |··········42|
f is |·····1.23457|
d is |·····3.14159|
Another example:

  // Set width to 10
std::cout << "|";
std::cout.width(10);
std::cout << "setw(10)";
std::cout << "|" << std::endl;
  // Set width to 15
std::cout << "|";
std::cout.width(15);
std::cout << "setw(15)";
std::cout << "|" << std::endl;
  // Set width to 20
std::cout << "|";
std::cout.width(20);
std::cout << "setw(20)";
std::cout << "|" << std::endl;
Output: (spaces are shown with a ·)

|··setw(10)|
|·······setw(15)|
|············setw(20)|
With printf, the value before the decimal point (e.g. %8.5f) was the width.

Padding with characters other than a space

Use the fill member of the cout object to modify the fill character:
cout.fill(fill-char);
Any padding that is added will use fill-char instead of the default space.

Executing this once before using cout:

std::cout.fill('*');
This will output something different:

  // Set width to 10
std::cout << "|";
std::cout.width(10);
std::cout << "setw(10)";
std::cout << "|" << std::endl;
  // Set width to 15
std::cout << "|";
std::cout.width(15);
std::cout << "setw(15)";
std::cout << "|" << std::endl;
  // Set width to 20
std::cout << "|";
std::cout.width(20);
std::cout << "setw(20)";
std::cout << "|" << std::endl;

Output:
|**setw(10)|
|*******setw(15)|
|************setw(20)|

Using setf for More Control

The setf member controls many aspects of the format.

Refer to tables 17.1 and 17.2 in the textbook for more information. These notes just scratch the surface of all of the functionality is provides.

A few examples to get you started:

double cost = 22.5; // $22.50
bool flag = true;

  // Default formatting for floating point: cost is 22.5 (significant digits)
std::cout << "cost is " << cost << std::endl;

  // Show trailing zeros: cost is 22.5000 (forces a decimal point and all 6 digits, even zero)
std::cout.setf(std::ios_base::showpoint);
std::cout << "cost is " << cost << std::endl;

  // Only 4 digits: cost is 22.50 (trailing zeros still in effect)
std::cout.precision(4);
std::cout << "cost is " << cost << std::endl;

  // Fixed-point, 2 digits to the right: cost is 22.50 (exact number of decimal digits)
  // Fixed means "decimal places", not "significant digits" (don't need showpoint above with this technique)
std::cout.setf(std::ios_base::fixed);
std::cout.precision(2);
std::cout << "cost is " << cost << std::endl;

  // Default formatting for boolean: flag is 1 (numeric)
std::cout << "flag is " << flag << std::endl;

  // Display true/false instead of 1/0: flag is true (text)
std::cout.setf(std::ios_base::boolalpha);
std::cout << "flag is " << flag << std::endl;
Outupt:
cost is 22.5
cost is 22.5000
cost is 22.50
cost is 22.50
flag is 1
flag is true

Changing justification

printfcout
  // Set the width, left justified
printf("i is |%-12i|\n", i);

Output:
i is |42          |
  // Set the width, left justified
std::cout << "i is |";
std::cout.width(12);

std::cout.setf(std::ios_base::left);
std::cout << i;
std::cout << "|" << std::endl;

Output:
i is |42          |

Comments:

Manipulators

Manipulators can be a more convenient way of formatting output. To use them, you must include another file:
#include <iomanip> // No .h extension
They work much the way some of the members work, including setf. In fact, they are just conveniences that call setf and unset behind the scenes.

Examples:

int i = 42;
float f = 1.23456789F;
double d = 3.141592653589793238426433832795;

std::cout << std::setprecision(3) << " f is |" << std::setw(6) << f << "|\n";
std::cout << std::setprecision(5) << " d is |" << std::setw(8) << d << "|\n";
Output:
 f is |  1.23|
 d is |  3.1416|
Compare the first statement above to this (written without manipulators):
std::cout.precision(3);
std::cout << " f is |";
std::cout.width(6);
std::cout << f << "|\n";
This long statement can be written in different ways:
  // One statement
std::cout << std::setprecision(5) << " d is |" << std::setw(8) << d << "|\n";
  // Individual statements
std::cout << std::setprecision(5);
std::cout << " d is |";
std::cout << std::setw(8);
std::cout << d;
std::cout << "|\n";
  // One statement on several lines
std::cout << std::setprecision(5)
          << " d is |" 
          << std::setw(8) 
          << d 
          << "|\n";
  // Unacceptable formatting
std::cout << std::setprecision(5)
      << 
  " d is |" << std::
      setw(8)  << 
    d 
  << "|\n";
More examples:
  // One statement across several lines
std::cout << std::setprecision(5)
          << " d is |" 
          << std::setfill('-')
          << std::left
          << std::fixed
          << std::setw(10) 
          << d 
          << "|\n";
          
          
Output:
 d is |3.14159---|
  // One statement across several lines
std::cout << std::hex
          << std::uppercase
          << " i is |" 
          << std::setfill('#')
          << std::left
          << std::setw(10) 
          << std::showbase 
          << i 
          << "|\n";

Output:
 i is |0X2A######|

Self-check: How would you print the above using printf? (Try it on your own.)

Some of the standard manipulators are shown in table 17.3 in the textbook.

More information on manipulators.

Overview of Input

Basics: To use cin, you must include the appropriate header file (same one used for cout)
#include <iostream> // No .h extension
Example:
int i;
float f;
double d;
char s[10];

  // Prompt user and read input
std::cout << "Enter an int: ";
std::cin >> i;

std::cout << "Enter a float: ";
std::cin >> f;

std::cout << "Enter a double: ";
std::cin >> d;

std::cout << "Enter a string: ";
std::cin >> s;

  // Display the input
std::cout << i << std::endl;
std::cout << f << std::endl;
std::cout << d << std::endl;
std::cout << s << std::endl;
Sample runs:
Enter an int: 45
Enter a float: 3.14
Enter a double: 3.18888889
Enter a string: digipen
45
3.14
3.18889
digipen
Enter an int: 10
Enter a float: 23.45
Enter a double: .8798
Enter a string: Supercalifragilistic
10
23.45
0.879761
Supercalifragilistic
Enter an int: 10
Enter a float: 23.45
Enter a double: .87987898
Enter a string: Supercalifragilisticexpialidocious
1869177711
1.72236e+22
7.8795e+199
Supercalifragilisticexpialidocious
On my Linux computer, when I run the second and third examples, I get this when the program ends:
*** stack smashing detected ***: program terminated
Aborted
Notes: