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.
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.
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.
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.
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.
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