III. Input/Ouput

 

Although input and output was introduced in Section II, we were really just scratching the surface of I/O in C++ programs. In this section, we dig a little deeper into C++ I/O, looking at various kinds of input statements, more complex output statements, and how to do file I/O.

 

A.   Background on I/O Streams

 

1.      C++ provides extensive support for I/O operations by providing prewritten operations for handling streams of characters.

 

2.      A stream is a sequence of characters from some source to some destination. There are two categories of streams:

 

a.       An input stream is a sequence of characters from an input device to the computer.

 

b.      An output stream is a sequence of characters from the computer to an output device.

 

c.       To use the keyboard and screen, every C++ program must include the header file iostream. This header file contains the definitions for two data types:

 

-         istream: The input stream data type.

 

-         ostream: The output stream data type.

 

d.      The iostream header file also contains two variable declarations:

 

-         istream cin: The input stream variable.

 

-         ostream cout: The output stream variable.

 

B.    Input Stream Processing

 

1.      The input stream variable cin and the extraction operator (i.e., >>) are used to input data from the standard input device.

 

2.      Example

 

int a;

char b;

double c;

string d;

 

cin >> a;

cin >> b;

cin >> c;

cin >> d;

 

Alternatively,

 

cin >> a >> b >> c >> d;

 

3.      A reading marker keeps track of the position in the input stream that the program should read next.

 

4.      Example

 

   AB   CD       FG\n

^

The character ‘\n’ is the newline character.

 

5.      The newline character indicates where one line ends and the next begins.

 

6.      Example

 

When you type

 

AB\n

CDE\n

FG\n

 

the program actually sees this as

 

AB\nCDE\nFG\n

 

because ‘\n’ is just another character in the input stream.

 

7.      The extraction operator follows four rules:

 

a.       Leading whitespace (i.e., blanks and non-printable characters, such as tabs and newline) is skipped.

 

b.      If the data type of a variable is char, then input for that variable stops after a single character is read (which is not consumed).

 

c.       If the data type of a variable is an int or double, then input for that variable stops at the first character that is not appropriate for the data type (e.g., whitespace or a character, and which is not consumed).

 

d.      If the data type is string, then input stops at the first trailing whitespace character (which is not consumed).

 

e.       Example

 

int a;

int b

char c;

char d;

double e;

 

cin >> a;                             type   -32, then a = 32

cin >> a >> b;                type 16  +64, then a = 16 and b = 64

cin >> a >> c >> e;    type    27  A  16.9, then a = 27, c = ‘A’, and e = 16.9

cin >> a >> b >> e;    type 12 8, then a = 12, b = 8, and the program waits for e

cin >> a >> e;                type 41 32.4 15, then a = 41, b = 32.4, and 15 is held for later

cin >> a >> c >> e;    type 25 A 16.9, then a = 25, c = ‘A’, and e = 16.9

cin >> a >> c >> e;    type 25\nA\n16.9, then a = 25, c = ‘A’, and e = 16.9

cin >> a >> c >> e;    type 25A16.9, then a = 25, c = ‘A’, and e = 16.9

 

8.      If the input stream contains more data items than are actually required by the program (i.e., not all data items typed in are consumed), the excess data items are discarded when the program terminates.

 

9.      If a char value is encountered in the input stream when an int or double is expected, this is a serious error resulting in input failure.

 

10.  Other methods for input stream processing require the use of predefined functions associated with the istream data type.

 

a.       These predefined functions are called istream member functions or stream member functions.

 

b.      To use a predefined function in a program, you need to know:

 

-         What the function does.

 

-         The name of the header file containing the function (and include it in your program).

 

-         The name of function.

 

-         The number of parameters in the function heading.

 

-         The order of the parameters in the function heading.

 

-         The type of each parameter in the function heading.

 

-         The type of value returned, if any.

 

-         Usage.

 

c.       Example

 

Need to calculate x to the power of y (i.e., xy). Since this is a common situation, C++ provides a facility for calculating x to the power of y. C++ provides the function pow in the cmath standard header file. The pow function takes two parameters: the base and the exponent (both of type double), and returns a value of type double.

 

#include <iostream>

#include <cmath>

 

using namespace std;

 

int main ()

{

    double x;

    double y;

    double z;

 

    cin >> x;

    cin >> y;

 

    z = pow (x, y);

 

    cout << z;

 

    return 0;

}

 

11.  The get stream member function is used to read character data, including whitespace, from the standard input device.

 

a.       The get function can only read one character at time and does not skip whitespace.

 

b.      The get function is called using dot notation, an operator that enables access to the functions that are defined for and associated with some data types.

 

c.       Example

 

Given

 

char c1;

char c2;

int a;

 

Type A 25. Then after executing

 

cin.get (c1);

cin.get (c2);

cin >> a;

 

c1 = ‘A’, c2 = ‘ ‘, and a = 25.

 

12.  The ignore stream member function is used to skip (i.e., read and discard) characters from the input stream.

 

a.       Example

 

Given

 

int a;

int b;

 

Type 957 34   1235\n128\n. Then after executing

 

cin >> a;

cin.ignore (100, ‘\n’);

cin >> b;

 

a = 957 and b = 128.

 

b.      Example

 

Given

 

char a;

char b;

 

Type ABCDE\nFGHI. Then after executing

 

cin.ignore (2, ‘\n’);

cin >> a;

cin.ignore (10, ‘\n’);

cin >> b;

 

a = ‘C’ and b = ‘F’.

 

13.  The putback stream member function is used to put the last character read by the get function back into the input stream.

 

14.  Example

 

The input stream is ABC\n.

 

char ch;

 

cin.get (ch);                      After executing this statement, ch = ‘A’ and the input stream is BC\n

cin.putback (ch);            After executing this statement, ch = ‘A’ and the input stream is ABC\n

 

15.  The peek stream member function is used to read the next character from the input stream without removing it from the input stream.

 

16.  Example

 

The input stream is ABC\n.

 

char ch;

 

ch = cin.peek ();            After executing this statement, ch = ‘A’ and the input stream is ABC\n

 

17.  The input stream variable cin and the extraction operator (i.e., >>) cannot be used to read a string containing embedded whitespace.

 

a.       Recall that input stops when whitespace is encountered.

 

b.      Example

 

Given

 

string name;

string course;

 

Type    Robert Hilderman    CS110. Then after executing

 

cin >> name >> course;

 

name = “Robert” and course = “Hilderman”.

 

18.  The getline function is used to read a string containing embedded whitespace.

 

a.       It does not skip leading whitespace.

 

b.      It reads characters up to the newline character (which is consumed, but not stored).

 

c.       Example

 

Given

 

string nameAndCourse;

 

Type Robert Hilderman    CS110. Then after executing

 

getline (cin, nameAndCourse);

 

nameAndCourse = “Robert Hilderman    CS110”.

 

19.  The clear stream member function restores an input stream to a working state after it has entered a fail state.

 

a.       Don’t worry too much about clear at this point, however, know that when a stream enters a fail state, all further I/O statements using that stream are ignored.

 

b.      Unless you check the state of a stream, your program could be generating incorrect results and you won’t necessarily know it. How this can be done will be discussed later.

 

c.       Example

 

Try compiling and running the following program:

 

#include <iostream>

 

using namespace std;

 

main ()

{

    int a;

    int b;

 

    cout << “Enter a: ”;

    cin >> a;

    cout << “Enter b: ”;

    cin >> b;

    cout << a + b + 35;

 

    return 0;

}

 

Run the program twice: entering 2 and 3 for a and b, respectively, for the first run, and entering A for the second run.

 

C.   Output Stream Processing

 

1.      One of the main reasons we write programs is to generate a solution to some problem.

 

a.       It would be nice if the output was suitable for human consumption.

 

b.      Fortunately, C++ provides facilities for such things as:

 

-         Controlling the number of decimal places.

 

-         Aligning columns.

 

-         Justifying text and numbers.

 

2.      Manipulators are special identifiers used to format output.

 

3.      The endl manipulator is used to do a carriage return and line feed (i.e., positions the stream insertion point at the beginning of the next line on the output device).

 

a.       As an aside, when output is sent to an output device, the output is first placed into a buffer.

 

b.      It is not until the buffer becomes full that the output is actually sent to the output device.

 

c.       However, the endl manipulator causes the buffer contents to be sent to the output device immediately.

 

4.      Example

 

cout << “This prints above” << endl;

cout << “This prints below”;

 

This prints above

This prints below is printed.

 

5.      The setw manipulator is used to control the number of characters occupied by the next value printed.

 

6.      Example

 

int i = 15;

int j = 2007;

 

cout << setw (4) << i << setw (5) << j;     prints   15 2007

cout << setw (1) << i << setw (2) <, j;     prints 152007

 

7.      Example

 

double x = 9.75;

 

cout << setw (4) << x;                       prints 9.75

cout << setw (6) << x;                       prints   9.75

cout << setw (3) << x;                       prints 9.75

 

8.      The fixed manipulator is used to force all subsequent floating point output to appear in decimal format.

 

9.      The scientific manipulator is used to force output to print in scientific notation format.

 

10.  Example

 

double x = 123456789.5;

 

cout << x;                prints 1.23457E+08 (on some systems)

cout << fixed << x;                   prints 123456789.5

cout << scientific << x;      prints 1.23457E+08

 

11.  The showpoint manipulator is used to force the decimal point to print.

 

12.  Example

 

double x = 95.0;

 

cout << x;                                      prints 95

cout << showpoint << x;         prints 95.0

 

13.  The setprecision manipulator is used to set the number of decimal places to print in all subsequent output.

 

14.  Example

 

double x = 2.64971;

 

cout << fixed;

cout << x;                                                     prints 2.64971

cout << setprecision (3) << x;   prints 2.650

 

15.  The left manipulator is used to force output to be left-justified.

 

16.  The right manipulator is used to force output to be right-justified.

 

17.  Example

 

Given

 

string name = “Robert Hilderman”;

string dept = “CS”;

int course = 110;

 

Then

 

cout << setw (20);

cout << right << name;

cout << setw (10);

cout << left << dept;

cout << course;

 

prints     Robert HildermanCS        110

 

18.  The setfill manipulator is used to set the fill character.

 

19.  Example

 

cout << setw (10) << setfill (‘-‘) << left << “Name”;

 

prints Name------

 

20.  The flush manipulator is used to clear the output buffer immediately, even if it is not full.

 

21.  From the above discussion, it can be seen that there are two types of manipulators:

 

a.       Those that require a parameter (e.g., setprecision, setw, setfill). When these are used, the header file iomanip must be included.

 

b.      Those that don’t require a parameter (e.g., endl, fixed, left). These are part of the iostream header file.

 

22.  To print a string that contains a double quote, the double quote must be preceded by the backslash (i.e., \).

 

23.  Example

 

cout << “Robert \“Bob\” Hilderman”;

 

prints Robert “Bob” Hilderman

 

Note that “ ” (i.e., the string containing one blank space) is not the same as “”. Similarly, “ ” is not the same as   (i.e., the string containing two blank spaces). Etc.

 

D.   File I/O

 

1.      Inputting data from the keyboard and outputting data to the screen works well as long as there isn’t too much data and as long as the data is not required for other purposes.

 

2.      A file is an area in secondary storage (e.g., disk or CD) containing persistent data.

 

a.       Input data is stored in files when the amount of data is large and/or we want to re-use the data.

 

b.      Output data is stored in files when we want to save it for archival purposes or use it as input to some other program.

 

3.      File I/O is similar to standard I/O:

 

a.       A header file containing the definitions for file stream data types is required.

 

-         You must include the fstream header file.

 

-         Example

 

#include <fstream>

 

-         The fstream header file defines the data types ifstream (input file stream) and ofstream (output file stream).

 

-         All the operators and functions that are valid for standard I/O are valid for file I/O (e.g., >>, get, getline, endl, fixed, left, etc.).

 

b.      File stream variables must be declared.

 

-         File stream variables are declared the same way that any other variable is declared.

 

-         Example

 

ifstream inFile;

ofstream outFile;

 

-         Note that this step is different from that for using cin and cout because this was done for us in iostream.

 

c.       The file stream variables must be associated with the physical files by opening the files.

 

-         Example

 

inFile.open (“your_input_file_name”);

outFile.open (“your_output_file_name”);

 

-         Opening an input file prepares a program to read by positioning the reading marker before the first character of the file.

 

-         Opening an output file for writing:

 

·        Creates a new file if the specified file doesn’t already exist.

 

·        Erases the contents of the specified file if it does already exist.

 

·        Prepares a program to write by positioning the writing marker at the beginning of the empty file.

 

d.      Use the file stream variables in I/O statements.

 

-         The syntax for using all the operators and functions is identical to the syntax for using cin and cout.

 

-         Example

 

int i;

char c;

double d;

string s;

 

inFile >> i >> c >> d >> s;

 

outFile << “i = “ << i << “ c = “ << c << “ d = “ << d << “ s = “ << s << endl;

 

inFile.get (c);

 

getline (inFile, s);

 

e.       Close the files when they are no longer required.

 

-         Example

 

inFile.close ();

outFile.close ();

 

-         Closing a file disassociates the file stream variable from the physical file.

 

-         Closing a file causes the output buffer to be cleared (i.e., all data is written to the file)

.

4.      File names can be set in two ways:

 

a.       At compile time (i.e., hard coded into the program).

 

b.      At run time.

 

c.       Example

 

ifstream inFile;

 

inFile.open (“c:\\salary.txt”);

 

Note that “c:\\salary.txt” is not actually of the C++ string type in this context. An argument to the open function must be something called a C-string. A C-string is a null-terminated sequence of characters of type char.

 

d.      Example

 

ifstream inFile;

string inFileName;

 

cout << “Enter the input file name: “;

cin >> inFileName;

inFile.open (inFileName.c_str ());

 

Note that the function c_str is a function associated with the C++ string type that converts a C++ string to a C-string.

 

E.    More on the string Data Type

 

1.      The string data type is a programmer-defined data type that is not actually a built-in part of the C++ language (i.e., it is provided in the C++ standard library).

 

a.       Recall that a string is a sequence of zero or more characters enclose in double quotes.

 

b.      Example

 

string myName = “Robert Hilderman”;

 

c.       Also recall that the first character is in position 0, the second in position 1, etc.

 

d.      Example

 

‘R’ is in position 0

‘o’ is in position 1

‘b’ is in position 2

...

‘n’ is in position 15

 

e.       An important property of strings is that they can be concatenated using string expressions.

 

f.        Example

 

string firstName = “Robert”;

string lastName = “Hilderman”;

string name;

 

name = firstName + “ ” + lastName;

 

2.      Additional string Operations

 

a.       The length (a.k.a. size) function returns an unsigned integer equal to the number of characters currently in a string.

 

b.      Example

 

string myName = “Robert Hilderman”;

string::size_type noOfChars;

 

noOfChars = myName.length ();                  sets noOfChars = 16

 

or

 

noOfChars = myName.size ();

 

The data type string::size_type is the type returned by the length and size functions. The type returned is system dependent, so rather than assuming that noOfChars should be unsigned int or unsigned long, use string::size_type.

 

c.       The find function searches a string to find the first occurrence of a sub-string and returns an unsigned integer equal to the position of the first character in the sub-string.

 

d.      Example

 

string firstName = “Robert”;

string lastName = “Hilderman”;

string::size_type position;

 

position = firstName.find (“bert”);               sets position = 2

position = firstName.find (“R”);                      sets position = 0

position = lastName.find (“bert”);                 sets position = string::npos

 

The data type string::size_type is the type returned by the find function. If the sub-string is found, then position is set accordingly. If the sub-string is not found, the value of a special constant string::npos is returned. This special constant is assigned the maximum possible value of the data type string::size_type (e.g., 4294967295 on some machines).

 

e.       The substring function returns a substring of a string.

 

f.        Example

 

string myName = “Robert Hilderman”;

string firstName;

string lastName;

 

firstName = myName.substr (0, 6);                    sets firstName = “Robert”

lastName = myName.substr (7, 9);                      sets lastName = “Hilderman”

firstName = myName.substr (4, 0);                    sets firstName = “” (i.e., the null string)

lastName = myName.substr (16, 20);                 program crashes!

 

The first argument of the string function is the start position of the sub-string to be found and the second argument is the length.

 

g.        The swap function interchanges the contents of two strings.

 

h.       Example

 

string firstName = “Robert”;

string lastName = “Hilderman”;

 

firstName.swap (lastName);             sets firstName = Hilderman and lastName = Robert

lastName.swap (firstName);             sets lastName = Hilderman and firstName = Robert