C++ I/O and formatting

Objectives

  • Use C++ I/O (cin, cout)
  • Format C++ output
  • Format output using printf

C++ I/O overview

  • I/O stands for input/output
  • I/O is treated as streams of bytes in C++
  • To use I/O in C++: #include <iostream>
  • To use I/O manipulators with parameters in C++: #include <iomanip>
  • Specify each item you will be using from that namespace
    • using std::cout;
    • using std::cin;
    • using std::endl;
  • Avoid this directive: using namespace std;
  • :: is the scope resolution operator; std::cout refers to the cout item in the std namespace
  • If you don't specify an item from a namespace with the using statement, you can still use the item by specifying the scope whenever you use it (eg. std::cin >> num)
  • One common style is to place the using statements only at the beginnings of functions which use those particular items.
  • Another common style is to avoid the using statements and specify the scope every place where it is needed in the code.
  • cin and cout are not C++ keywords; they are variables defined in the iostream header file
  • cin is an istream and is used for input, usually keyboard
  • cout is an ostream and is used for output, usually screen
  • I/O manipulators without parameters are defined within ios. This includes: left, right, fixed, showpoint, scientific
  • I/O manipulators with parameters are defined within iomanip. This includes: setw, setprecision, setfill
  • To use the old C I/O: #include <cstdio>

The extraction operator

  • The extraction operator is used with istreams: >>
  • Read keyboard input into the variable num: cin >> num;
  • The extraction operator will read what it has to from the specified istream to satisfy its variable operand.
  • By default, only basic data types can be input with the extraction operator.
  • We will see later how to make classes that let the extraction operator handle their input.
  • If the input does not match the variable type, the input operation will fail.
  • Multiple items can be read from istream at once: cin >> num1 >> num2;
  • The extraction operator skips whitespace and newlines, so other functions are available to read any characters, including whitespace.
  • Since whitespace is used as a separator, a different technique (getline) is used to read in text which may contain whitespace.
  • One fundamental difference between using cin << and getline is whether the newline at the end of input is removed from the buffer and whether a newline at the start of the buffer is skipped. The basic rule is that cin does not remove the newline and ignores it at the start of the buffer. The getline function does the opposite. If you are mixing the two, then you almost certainly want to use a cin.ignore() after using cin << so getline works properly.

The insertion operator

  • The insertion operator is used with ostreams: <<
  • Display variables num and x on screen: cout << num << ", " << x;
  • By default, only basic data types can be output with the insertion operator.
  • We will see later how to make classes that let the insertion operator handle their output.
  • There are a number of formatting options available (covered below).

Input functions

  • cin.get(charVar): reads next character into charVar, including whitespace
  • cin.ignore(intVar, charExpr): ignores the next intVar characters or until charExpr is encountered, whichever comes first
  • charVar = cin.peek(): allows access to next character in istream, but doesn't remove it from istream
  • cin.putback(charVar): places charVar at start of istream
  • getline(istreamVar, stringVar): reads an entire line from the specified istream into stringVar
  • See cinfunc.cpp for a demonstration of istream functions

Formatted I/O using iostream and iomanip

There are a number of ways of setting the stream manipulations shown below. For simplicity, we will stick with one style for this week.

  • Non-paramterized stream manipulators (defined in <ios>)
    • endl - add newline and flush buffer
    • flush - flush output buffer to destination
    • skipws - skip white space in input
    • left - left-align values, padding on right with the fill char
    • right - right-align values, padding on left with the fill char
    • internal - use fill char after leading sign or base indication, but before value
    • dec - format numeric values as base 10
    • oct - format numeric values as base 8
    • hex - format numeric values as base 16
    • boolalpha - display bool values as the text "true" or "false"
    • noboolalpha - display bool values as the integers 0 or 1
    • showbase - display numeric constants with leading base indicator if applicable
    • noshowbase - don't display numeric constants with leading base indicator
    • showpoint - show decimal point and trailing zeros for floating-point values
    • noshowpoint - don't show decimal point and trailing zeros for floating-point values if not needed
    • uppercase - display uppercase A through F for hexadecimal values and E for scientific values
    • nouppercase - display lowercase a through f for hexadecimal values and e for scientific values
    • showpos - show plus signs (+) for positive values
    • noshowpos - don't show plus signs (+) for positive values
    • Note: ostream starts in a general format, choosing fixed or scientific as the need arises
    • scientific - display floating-point numbers in scientific format
    • fixed - display floating-point numbers in fixed format
    • Note: no easy manipulator for returning ostream to general format
    • You can use setiosflags(ios::fixed | ios::scientific) to return to general format
  • Parameterized stream manipulators (defined in <iomanip>)
    • setw(intVar) - sets the field width; only aplies to next value output
    • setprecision(intVar) - sets the digits displayed after the decimal in fixed and scientific formats; the number of significant digits in general format
    • setfill(charVar) - set fill character to charVar
  • See manips.cpp sample code
  • Richard Rasala's handout on C++ IO Manipulators
  • A good reference for iostream
  • A brief online document regarding IO manipulators

Formatted I/O using printf

Using stringstream

  • Formatted messages used to be put together quickly using sprintf with a character buffer and the printf format rules. The buffer could then be converted to a C++ string object if needed. This technique has become problematic since some compilers produce security warnings and errors using the old C formatting techniques. To be cross platform these days in C++, it is better to use the slightly more cumbersome (but also more flexible and safer) stringstream class.
  • Include <sstream> to use stringstream.
  • Create a stringstream object as follows: stringstream varName;
  • Use the stringstream reference just like you would use cout.
  • When done constructing the stringstream, you can create a C++ string object from it using its str() member function.
  • See the example program: testSstream.cpp

Input validation

  • C++ has many problems with doing easy input validation.
  • One problem is that cin and getline treat newlines and whitespace differently.
  • That is a problem since you generally need both cin and getline, often interspersed.
  • The best solution is often to create your own resusable input library.
  • See the example programs at: