What We Will Cover
Continuations
Homework Questions?
^ top
7.1: Streams and File I/O
Objectives
At the end of the lesson the student will be able to:
- List the types of files
- Describe the purpose of a stream
- Read and write text files
|
^ top
7.1.1: About Program I/O
- Program I/O = Program Input/Output
- Input to and output from programs
- Input can be from a keyboard, mouse or file
- Output can be to a display screen, printer or file
- Note that files can be both input and output devices for programs
- Advantages of file I/O
- Data still exists after the program ends
- Input can be automated (rather than entered manually)
- Output from one program can be input to another
- To store and retrieve data in a file, we need two items:
- A file
- A file stream object
- We will look at files first
^ top
7.1.2: Files
File: a collection of data stored under a common name on a storage medium.
- Files provide long-term storage of large amounts of data
- Usually, you store files on non-volatile storage mediums
- Magnetic disks
- Optical disks
- Flash storage, like USB storage devices
- File are a single sequence of bytes
| Byte 0 |
Byte 1 |
Byte 2 |
... |
Byte n−1 |
End-of-file marker |
- The OS keeps track of the number of bytes in a file
- Using either an end-of-file marker or counting the number of bytes
- Files must have a name
- Naming requirements depend on the underlying operating system (OS)
- The OS organizes files into directories
^ top
7.1.3: Types of Files
- All data and programs are ultimately just zeros and ones
- Each binary digit can have one of two values: 0 or 1
- A bit is one binary digit
- A byte is a group of eight bits
- Programs group files into two broad categories: text and binary
Text Files
- In text files, the bits represent printable characters
- Files are usually stored as one byte per character (ASCII)
- Each record (like a line) are often delimited by end-of-line characters
- Macintosh (before OS-X): "
\r"
- Unix: "
\n"
- Windows: "
\r\n"
- Individual fields within a record are often delimited by commas, tabs or other special characters
- Source code is stored as a text file
- You can read text files because each byte is translated by display devices into readable characters
Binary Files
- Everything other than text is called binary
- Each bit represents some type of encoded information
- E.g.: program instructions or numeric data
- Binary files are easily read by the computer but not by humans
For Example
- If we wanted to store an
int value of 1234 in a file
- We know an
int is four bytes long
- We can store our value as either
1234 or "1234"
- How we store it determines what is actually written to the file
| Description |
Byte 0 |
Byte 1 |
Byte 2 |
Byte 3 |
(int) 1234 as binary bits |
00000000 |
00000000 |
00000100 |
11010010 |
(int) 1234 as bytes |
0 |
0 |
4 |
210 |
"1234" as char's |
'1' |
'2' |
'3' |
'4' |
| "1234" as ASCII codes |
49 |
50 |
51 |
52 |
^ top
7.1.4: Streams
Stream: a one-way transmission path that either delivers data to a destination (screen, file, etc.) or that takes data from a source (keyboard, file, etc.)
- A stream connects a program to an I/O object
- Input stream: an object that provides a sequence of bytes to a program

- Output stream: an object that accepts a sequence of bytes from a program

cin and cout are input and output streams
File Streams
File stream: a one-way transmission path used to connect a program to a file.
- File streams can be either input or output streams
- File input streams receive data from a file
- File output streams send data to a file
- File I/O also uses streams of type
ifstream and ofstream
- Each file your program uses will need a separate file stream object
Streams and objects
- Streams are objects and thus
cin and cout are objects
- Objects are special variables that can have a function associated with them
- To call a function of an object, you use the dot operator
- That is why we use the following code to format output
cout.setf(ios::fixed); // fixed notation, not scientific
cout.setf(ios::showpoint); // show decimal point
cout.precision(2); // show 2 decimal places
^ top
7.1.5: Example of File I/O
- As an example, let us write an application that reads and writes files
- We read a file named
infile.txt, which contains the following 3 values:
10
20
30
We sum the numbers and write the sum to a second file named outfile.txt
What do you notice that is different about the following code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
/**
* Reads three numbers from the file infile.txt,
* sums the numbers, and writes the sum to the
* file outfile.dat.
*/
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ifstream fin;
ofstream fout;
fin.open("infile.txt");
if (fin.fail()) {
cout << "Input file opening failed.\n";
exit(1);
}
fout.open("outfile.txt");
if (fout.fail()) {
cout << "Output file opening failed.\n";
exit(1);
}
int first, second, third;
fin >> first >> second >> third;
fout << "The sum of the first 3\n"
<< "numbers in infile.txt\n"
<< "is " << (first + second + third)
<< endl;
fin.close();
fout.close();
cout << "Processing completed\n";
return 0;
}
|
- How does the program get its input?
- Where is the program output?
^ top
7.1.6: Procedure For File I/O
- Place the following include directives in your program file:
#include <fstream> // for file I/O
#include <iostream> // for cout
using namespace std;
- Declare names for input and output streams
ifstream fin;
ofstream fout;
- Connect each stream to a file using
open() and check for failure
fin.open("infile.txt");
if (fin.fail()) {
cout << "Input file failed to open.\n";
exit(1);
}
fout.open("outfile.txt");
if (fout.fail()) {
cout << "Output file failed to open.\n";
exit(1);
}
- Read or write the data.
- Read from a file with
fin like using cin
fin >> first >> second >> third;
- Write to a file with
fout like using cout
fout << "first = " << first << endl;
- Close the streams when finished
fin.close();
fout.close();
^ top
7.1.7: Summary
- Programs use streams for input and output
cin and cout are types of streams
- File I/O also uses streams of type
ifstream and ofstream
- Streams are objects and have functions associated with them
- Some of the functions we call for file I/O include:
open("fileName"): establishes a connection from the stream to the file
fail(): tests the stream for errors
close(): closes the connection of the stream to the file
- You use input streams like you use
cin
fin >> first >> second >> third;
You use output streams like you use cout
fout << "first = " << first << endl;
To halt execution of your program on error, use the exit function
exit(1);
Check Yourself
- What is used to connect a program to a file?
- What library is required for file I/O?
- How are streams declared?
- What stream function is used to open a file?
- What stream function is used to check that a file opened correctly?
- How do you read and write data using a stream?
- Why should you close a stream after you are done using it in your program?
^ top
Exercise 7.1
In this exercise we write a program that copies one line of text from an input stream to an output stream.
Specifications
- Save the following code as
copyone.cpp.
- Save the file infile.txt to the same directory as your program source code.
- Declare and open an input stream named
fin that reads from infile.txt.
- Declare and open an output stream named
fout that writes to a file named outfile.txt.
- Add code to read the first number from the input stream and save it to the output stream.
- Add code to close both of the streams.
- Compile and run your program.
- View the
outfile.txt file using TextPad or WordPad to verify that one number was copied.
- View the output with Notepad after you verify the program is working. Notice how Notepad cannot handle the end of line characters for Unix.
- Submit your program as the answer to this exercise.
1
2
3
4
5
6
7
8
|
#include <iostream>
using namespace std;
int main() {
// Enter code here
return 0;
}
|
^ top
7.2: More I/O Topics
Objectives
At the end of the lesson the student will be able to:
- Append data to files
- Check for end-of-file conditions
- Code user input as file names
- Code stream parameters in functions
|
^ top
7.2.1: Alternative Syntax for Open
- It is possible to create a stream and open a file in one step
- Rather than:
ofstream fout;
fout.open("messages.txt");
You can use:
ofstream fout("important.txt");
^ top
7.2.2: Appending to a File
- The standard open operation for writing begins with an empty file
- Even if the file exists you loose all the contents
- To prevent loosing the information, you must open for appending to the file
ofstream fout;
fout.open("important.txt", ios::app);
If the file doesn't exist then ofstream creates it
If the file exists then ofstream positions itself to append to the end
The second argument is a constant defined in class ios
For Example
- The following program will add a message to the file every time we run it
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#include <fstream>
#include <iostream>
using namespace std;
int main() {
string message;
cout << "Enter a message to add to the file: ";
getline(cin, message);
ofstream fout;
fout.open("messages.txt", ios::app);
if (fout.fail()) {
cout << "Output file opening failed.\n";
exit(1);
}
fout << message << endl;
fout.close();
cout << "See you later!\n";
return 0;
}
|
^ top
7.2.3: Checking for End-of-File
- Sometimes you do not know how many lines are in a file
- To solve this, the typical approach is to use a loop to process the file
- Then we use a sentinel value from the file input to end the loop
- Whenever our program does a read operation it returns a
bool value
- We can use this
bool value as our sentinel
For Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#include <fstream> // for file I/O
#include <iostream>
using namespace std;
int main() {
ifstream fin;
fin.open("infile.txt");
if (fin.fail()) {
cout << "Input file failed to open.\n";
exit(1);
}
double nextNum, sum = 0;
int count = 0;
while(fin >> nextNum) {
cout << "Read: " << nextNum << endl;
sum = sum + nextNum;
count++;
}
cout << "average = " << (sum / count) << endl;
fin.close();
return 0;
}
|
- The expression
(fin >> next) returns true if successful
- Returns
false if the program attempts to read beyond the end of a file
Reading Complete Lines
- Sometimes you need to read and process an entire line
- For this, we can use the
getline() function of the string class
- This works in a loop as well:
while(getline(fin, line)) {
cout << line << endl;
}
^ top
7.2.4: File Names as Input
- Note that the argument to
open() is a string type
fin.open("infile.txt");
Instead of a literal string, we can use a string variable
However, we must use the c_str() function to convert to a C-string
For Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#include <fstream> // for file I/O
#include <iostream>
using namespace std;
int main() {
string filename, line;
cout << "Enter a file name: ";
cin >> filename;
ifstream fin;
fin.open(filename.c_str());
if (fin.fail()) {
cout << "Input file failed to open.\n";
exit(1);
}
while(getline(fin, line)) {
cout << line << endl;
}
return 0;
}
|
^ top
7.2.5: Stream Parameters
- Stream types can be formal parameters in functions
- However, they must be call-by-reference parameters
void sayHello(ofstream& aStream) {
aStream << "hello\n";
}
Note that it is possible to leave out the 'f' in the stream parameter
This would give us a function like:
void sayHello(ostream& aStream) {
aStream << "hello\n";
}
ostream (no 'f') parameters accepts cout or ofstream objects as arguments
Similarly, istream (no 'f') parameters accept cin or ifstream objects as arguments
Using this feature, we can make functions work for both files and user I/O
For Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
#include <fstream> // for file I/O
#include <iostream>
using namespace std;
/**
* Outputs a line to the ostream.
*
* @param aStream the output stream
* @param line The string to output
*/
void output(ostream& aStream, string line);
int main() {
ifstream fin;
fin.open("infile.txt");
if (fin.fail()) {
cout << "Input file opening failed.\n";
exit(1);
}
ofstream fout;
fout.open("outfile.txt");
if (fout.fail()) {
cout << "Output file opening failed.\n";
exit(1);
}
string line;
while(getline(fin, line)) {
output(cout, line);
output(fout, line);
}
return 0;
}
void output(ostream& aStream, string line) {
aStream << line << endl;
}
|
^ top
7.2.6: Other File Operations
- Some file operations are not supported by C++ streams
- In these cases, you use the C-style functions
- Note that these functions take C-string arguments
- Thus you must use the
c_str() function when using string variables
Commonly Used C-Functions for File Manipulation
| Function |
Description |
| remove(fileName) |
Deletes the file specified by the C-string fileName. |
| rename(oldName, newName) |
Changes the file or directory name specified by the C-string oldName to the newName. |
| perror(message) |
Print the error message specified by the C-string along with the system error message. |
| system(command) |
Executes a command specified by the C-string like you were using the command line. |
Example to Remove a File
string fileName;
cout << "File to remove: ";
cin >> fileName;
int result = remove(fileName.c_str());
if (result == 0) {
cout << "File successfully removed\n";
} else {
perror("Error removing file\n");
}
Example to Rename a File
int result;
string oldName, newName;
cout << "Old file name: ";
cin >> oldName;
cout << "New file name: ";
cin >> newName;
result = rename(oldName.c_str(), newName.c_str());
if (result != 0 ) {
perror( "Error renaming file" );
}
Examples Using system() Function
system("ls"); // list files
system("clearn"); // clear the screen
^ top
7.2.7: Summary
- The standard open operation will create an empty file
- You can open a file for appending data by using an extra argument
ofstream fout("important.txt", ios::app);
Sometimes you do not know how many lines are in a file
To solve this, the typical approach is to use a loop to process the file
while(fin >> line) {
cout << line << endl;
}
You can use string variables to open files
However, we must use the c_str() function to convert to a C-string
ifstream fin;
fin.open(filename.c_str());
Streams can be arguments to a function, but you must use call-by-reference
Type istream for function parameters works for both cin and ifstream
Type ostream for function parameters works for both cout and ofstream
Check Yourself
- How do you keep a file opened for writing from destroying existing information?
- What looping structure do you use to read every number in a file?
- What looping structure do you use to read every line of a file?
- What string function do you use to convert a
string to a C-string?
- How do you code streams as parameters for a function?
^ top
Exercise 7.2
In this exercise we explore reading all the lines of a file using a loop.
Specifications
- Copy the following code into a text editor and save the file as
showfile.cpp.
- Stub out the function
toScreen() and call the function toScreen() from main().
- Define the function
toScreen() so that it reads one line at a time from the input stream parameter using function getline() and displays each line it reads to the screen.
- Submit your program along with your other exercises for this lesson.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#include <fstream> // for file I/O
#include <iostream>
using namespace std;
void toScreen(ifstream& fin);
int main(void) {
string filename, line;
cout << "Enter a file name: ";
cin >> filename;
ifstream fin;
fin.open(filename.c_str());
if (fin.fail()) {
cout << "Input file failed to open.\n";
exit(1);
}
// Call function toScreen() here
return 0;
}
// Add new function toScreen() here
|
^ top
7.3: Formatting Output
Objectives
At the end of the lesson the student will be able to:
- Write code using output formatting functions
- Write code using manipulators
|
^ top
7.3.1: Formatting Functions
- Formatting functions are used to set the layout of the output
- These same functions apply to
cout
- precision: sets the number of digits to display for floating-point numbers
fout.precision(2);
setf: sets a format flag for the stream
fout.setf(ios::fixed); // Fixed notation
fout.setf(ios::scientific); // Scientific notation
fout.setf(ios::showpoint); // show decimal point
fout.setf(ios::showpos); // Show + signs
fout.setf(ios::right); // Right justify
fout.setf(ios::left); // Left justify

unsetf: clears a format flag
fout.unsetf(ios::showpos); // No more + signs
width: set or return the field width
- Only applies to next item that is output
- Width expands automatically so that entire item is always output
fout.width(3);
fout << 3 << endl; // ouputs <space><space>3
fout << 123.45 << endl; // ouputs 123.45
For Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
#include <fstream> // for file I/O
#include <iostream>
using namespace std;
/**
* Outputs a line to the ostream.
*
* @param aStream the output stream
* @param line The string to output
*/
void formatOutput(ostream& aStream, double number);
int main() {
double number;
cout << "Enter a number and I will format it: ";
cin >> number;
ofstream fout;
fout.open("formatted.txt", ios::app);
if (fout.fail()) {
cout << "Output file opening failed.\n";
exit(1);
}
formatOutput(cout, number);
formatOutput(fout, number);
return 0;
}
void formatOutput(ostream& aStream, double number) {
aStream << "The formatted number is (";
aStream.setf(ios::fixed);
aStream.setf(ios::showpoint);
aStream.setf(ios::showpos);
aStream.setf(ios::right);
aStream.precision(3);
aStream.width(10); // only applies to next output
aStream << number << ")" << endl;
}
|
^ top
7.3.2: Manipulators
- Manipulator: a function called in a nontraditional way
- Manipulators in turn call member functions
- Manipulators may or may not have arguments
- To use manipulators you may need to include:
#include <iomanip>
using namespace std;
endl: outputs a newline character
setw: sets the field width from that point onward
cout << "Start" << setw(4) << 10 << setw(6) << 20;
setprecision: sets the number of digits of precision
cout << "$" << setprecision(2) << 7.3 << endl;
Further information: C++ I/O Flags (includes manipulators)
For Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
#include <fstream> // for file I/O
#include <iostream>
#include <iomanip>
using namespace std;
/**
* Outputs a line to the ostream.
*
* @param aStream the output stream
* @param line The string to output
*/
void formatOutput(ostream& aStream, double number);
int main() {
double number;
cout << "Enter a number and I will format it: ";
cin >> number;
ofstream fout;
fout.open("formatted.txt", ios::app);
if (fout.fail()) {
cout << "Output file opening failed.\n";
exit(1);
}
formatOutput(cout, number);
formatOutput(fout, number);
return 0;
}
void formatOutput(ostream& aStream, double number) {
aStream << "The formatted number is ("
<< fixed
<< showpoint
<< showpos
<< right
<< setprecision(3)
<< setw(10)
<< number << ")" << endl;
}
|
^ top
7.3.3: Example of Formatting Data
- Following example is adapted from textbook pages 526-527
- As an example of formatting data, consider the following data file:
1
2
3
4
5
|
12.34 -9.87654
2.3131 -89.506
12.33333333 92.8765
-1.234567e2
|
- We want to write a program to take the raw data from the file and format it neatly
- Also, we will write first to the screen and a then to a file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
/**
* Reads all the numbers in the file rawdata.txt
* and writes the numbers to the screen and to
* the file neat.txt in a neatly formatted way.
*/
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
void formatData(istream& messyFile, ostream& neatFile,
int precision, int fieldWidth);
int main()
{
ifstream fin;
fin.open("rawdata.txt");
if (fin.fail()) {
cout << "Input file opening failed.\n";
exit(1);
}
ofstream fout;
fout.open("neat.txt");
if (fout.fail()) {
cout << "Output file opening failed.\n";
exit(1);
}
formatData(fin, cout, 5, 12);
// Close and reopen input file
fin.close();
fin.clear(); // allows reuse of stream
fin.open("rawdata.txt");
if (fin.fail()) {
cout << "Input file opening failed.\n";
exit(1);
}
formatData(fin, fout, 5, 12);
fin.close();
fout.close();
cout << "End of program.\n";
return 0;
}
void formatData(istream& messyFile, ostream& neatFile,
int precision, int fieldWidth) {
neatFile.setf(ios::fixed);
neatFile.setf(ios::showpoint);
neatFile.setf(ios::showpos);
neatFile.precision(precision);
double next;
while (messyFile >> next) {
neatFile << setw(fieldWidth) << next << endl;
}
}
|
^ top
7.3.4: Summary
- C++ has many formatting functions to set the layout of the output
- You can use them with
cout and any ofstream type
- You can use manipulators to change formatting within the stream
- Affects output after the manipulator is used and onwards
- You can use manipulators to format one value at a time
Check Yourself
- How do you set the width of a field when outputting numbers?
- After you set the width of a numeric field, how long does the setting last?
- If the number you display needs more digits than the specified width, does the entire number get displayed?
- By default, is numerical output left or right justified?
- What is meant by the term manipulator?
^ top
Exercise 7.3
- Start a text file named exercise7.txt.
- Prepare the exercise header as described in the HowTo on submitting exercises
- Label this exercise: Exercise 7.3
- Complete the following and record the answers to any questions in exercise7.txt.
Specifications
- Run the following code:
#include <iostream>
#include <iomanip>
using namespace std;
int main(void) {
cout << "*";
cout.width(5);
cout << 123
<< "*" << 123 << "*" << endl;
cout << "*" << setw(5) << 123
<< "*" << 123 << "*" << endl;
return 0;
}
Q1: To how many number fields does width() or setw() apply?
- Run the following code:
#include <iostream>
#include <iomanip>
using namespace std;
int main(void) {
cout << "*" << setw(5) << 123;
cout.setf(ios::left);
cout << "*" << setw(5) << 123;
cout.setf(ios::right);
cout << "*" << setw(5) << 123 << endl;
return 0;
}
Q2: By default, are numbers output ios::left or ios::right?
- Run the following code:
#include <iostream>
#include <iomanip>
using namespace std;
int main(void) {
cout << "*" << setw(3) << 12345 << "*\n";
return 0;
}
Q3: How many digits are displayed? Why?
^ top
7.4: Midterm Preparation
Objectives
At the end of the lesson the student will be able to:
- Discuss how to prepare for the first midterm exam
- Describe how to take the first midterm exam
|
^ top
7.4.1: About the Exam
- You must attend the exam or you will receive a score of zero (0)
- Except by prior arrangement with the instructor
- I am using WebCT to administer the test
- The exam is closed books and closed notes
- However, you may have one 3" x 5" card of notes for the exam
- You must turn in your 3" x 5" card after the exam
- You may use your computer, but only to take the exam in WebCT
- You may have a sheet of blank scratch paper
- You may NOT use the computer to compile or run programs
- You may NOT use the computer to view documents on the Internet
- You may NOT use a calculator or other electronic device
- You may NOT communicate with anyone but the instructor during the exam
^ top
7.4.2: Recommended Preparation
- Work through the Practice Midterm Exam questions in WebCT
- Working the problems in groups is encouraged
- Get explanations for anything you do not understand
- Review the instructor's notes and make sure you can answer the Check Yourself questions, making notes about anything that you do not know
- Review your notes and prepare your 3" x 5" card
- Review your homework assignments and solutions
- Review your CodeLab exercises
- You should be prepared to write short programs
- Mathematical expressions
- User I/O
- Conditional statements
- Testing multiple conditions
- char "arithmetic"
- "main" loops
- Counter-controlled loops
- Accumulating values in a loop
- Using library functions (
pow(), rand(), sqrt(), etc.)
- Declaring and defining functions
- Call-by-value
- Call-by-reference
- File I/O
- A few more tips:
- I try to use questions containing actual code
- More quiz tips: Basic Rules For Taking a Multiple-Choice Test
^ top
7.4.3: Exam Taking Tips
- Save after every answer -- you can always choose another answer
- If you get stuck on a question, make your best guess and return later
- If you are equally uncertain between two choices, go with first impression
- You do not need to comment code for tests and exams
- Unless specifically instructed to in the exam question
- Use the full time available
- Use any remaining time to check your work
^ top
7.4.4: Questions and Answers
^ top
Wrap Up
^ top
Home
| WebCT
| Announcements
| Day Schedule
| Eve Schedule
Course info
| Help
| FAQ's
| HowTo's
| Links
Last Updated: November 05 2005 @17:19:14
|