What We Will Cover
Continuations
Homework Questions?
^ top
10.1: Streams and File I/O
Learner Outcomes
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
10.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
10.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 operating system keeps track of the number of bytes in a file
- Files must have a name
- Naming requirements depend on the underlying operating system (OS)
- The operating system organizes files into directories
^ top
10.1.3: Types of Files
- All data in a file is 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
- These binary digits may represent integer values or text characters
- It is up to the program using the file to understand the meaning and internal format of the data
- In general, programs interpret data using 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 line is delimited by end-of-line characters:
- Macintosh (before OS-X): "
\r"
- Unix: "
\n"
- Windows: "
\r\n"
- An example of a text file is source code
- You can read text files because each byte is interpreted by a program as textual characters
- Some of these programs, like TextPad, then display the textual data to your computer's screen
- Since there are many programs that read and display text, text files are called human readable
Binary Files
- Data other than text is usually referred to as binary data
- Each bit represents some type of encoded information
- Such as program instructions or integer data
- Binary files are easily read by the computer but not by humans
- The following table compares binary and text values saved in a file
- First we consider the value "1234" as ASCII codes and compare these bits to a binary value of
1234
- As we can see, the bit patterns are different for the same data when stored as text and binary
Comparing Binary and Textual Data
| Description |
Byte 0 |
Byte 1 |
Byte 2 |
Byte 3 |
"1234" as char's |
'1' |
'2' |
'3' |
'4' |
| "1234" as ASCII codes (bytes) |
49 |
50 |
51 |
52 |
| "1234" as ASCII codes (bits) |
00110001 |
00110010 |
00110011 |
00110100 |
(int) 1234 as binary bits |
00000000 |
00000000 |
00000100 |
11010010 |
^ top
10.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 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
- An example of using the dot operator is with cout is shown below
cout.setf(ios::fixed); // fixed notation, not scientific
cout.setf(ios::showpoint); // show decimal point
cout.precision(2); // show 2 decimal places
^ top
10.1.5: Example of File I/O
- Let us consider an example that reads from a file and writes to a file
- The program reads from a file named
infile.txt, which contains the following values:
10
20
30
- After summing the values, the program writes them to a file named
outfile.txt
- Consider the following code and try to identify:
- What is the name of the input stream?
- Which line opens a file for reading
- What is the name of the output stream?
- Which line opens a file for writing
- Which line reads data from the input stream?
- Which lines write data to the output stream?
Example Program to Read and Write Files
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
|
/**
Reads three numbers from the file infile.txt,
sums the numbers, and writes the sum to the
file outfile.txt.
*/
#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 opening failed.\n";
exit(-1);
}
ofstream fout;
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;
}
|
Closing a Stream
- After finishing reading and writing you should close the file streams
- If you do not close an output stream, you may lose data stored in the output buffer
- In addition, streams consume system resources and you should not keep open any more streams than needed
^ top
10.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:
- Close the streams when finished reading and writing:
fin.close();
fout.close();
More Information
^ top
Exercise 10.1
In this exercise we write a program that copies two numbers from an input stream to an output stream.
Specifications
- Copy the following program into a text editor, save it as
copytwo.cpp, and then compile and run the starter program to make sure you copied it correctly.
#include <iostream>
using namespace std;
int main() {
// Enter your code here
return 0;
}
- Save the file infile.txt to the same directory as your program source code.
We will read from this file after writing our program.
- Place the following include directives in your source code file:
#include <fstream> // for file I/O
#include <iostream> // for cout
using namespace std;
- Inside
main(), declare names for the input and output streams:
ifstream fin;
ofstream fout;
- Add code to 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);
}
- Add statements to read two numbers from the input stream. For example, here is possible code for reading the first number:
int first;
fin >> first;
- Add statements to write the two numbers to the output stream. For example, here is possible code for writing the first number:
fout << "first = " << first << endl;
- Close the streams when finished reading and writing:
fin.close();
fout.close();
- Compile and run your modified program to make sure you made the changes correctly.
Notice that you do not see any output on the screen for file reading or writing. The output stream wrote the program output to the output file.
- Using TextPad or WordPad, open the output file you created and verify that two numbers were copied. Your output file should look like:
first = 10
second = 20
- Using Notepad, open the output file you created and compare the output with what you saw in TextPad or WordPad.
Notice how Notepad cannot display the end of line characters for Unix. However, TextPad and WordPad can display Unix end-of-line characters correctly.
- Submit your program source code to Blackboard as part of assignment 10.
Listing of copytwo.cpp

Check Yourself
As time permits, be prepared to answer these questions. You can find more information by following the links after the question.
- What two items are needed to connect a file to a program? (10.1.1)
- What is a file? (10.1.2)
- What are the two types of files? (10.1.3)
- What is used to connect a program to a file? (10.1.4)
- What library is required for file I/O? (10.1.6)
- How are input and output streams declared? (10.1.6)
- What stream function is used to open a file? (10.1.6)
- What stream function is used to check that a file opened correctly? (10.1.6)
- How do you read and write data using a stream? (10.1.6)
- Why should you close a stream after you are done using it in your program? (10.1.5)
^ top
10.1.7: Summary
^ top
10.2: Reading Data From Files
Learner Outcomes
At the end of the lesson the student will be able to:
- Read data of various types from a file
- Check for end-of-file conditions
- Read data from a file in a loop
|
^ top
10.2.1: Reading Data Using an Input Stream
Reading From a File
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ifstream fin;
fin.open("infile.txt");
if (fin.fail()) {
cout << "Input file opening failed.\n";
exit(-1);
}
double num;
fin >> num;
cout << "Read data: " << num << endl;
fin.close();
return 0;
}
|
^ top
10.2.2: Using Loops to Read Files
- Sometimes you do not know how many data items are in a file
- To solve this, the typical approach is to use a loop to process the file
- When reading input from the console, we can read the input in the test condition
- While the read is successful, the input stream returns a value interpreted as
true
- If the stream fails or closes, then the test condition fails
- This failing condition returns a value interpreted as
false by the loop
- Thus the loop stops and the program continues after the loop
- We can use this behavior to read from a file as shown below
Example Program Reading a File Using a Loop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#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;
}
|
^ top
10.2.3: Controlling File Loops with Boolean Variables
- Another way to control loop termination is to use a boolean variable
- To use boolean variables as a test condition for file loops, we code something like:
bool more = true;
while (more) {
fin >> next;
if (fin.fail()) {
more = false;
} else {
// process input
}
}
- The advantage of using a boolean variable is we can code multiple conditions for exiting a loop
- Note that the following conditions have extraneous information:
while (more == true) // instead use: while (more)
while (more == false) // instead use: while (!more)
- The reason is that
== true and != false are not needed for correct operation
- You can see an example use of a boolean variable for reading files in the following program
Example Program Using a Boolean Variable for the Loop Test
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
|
#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 next = 0;
double highest = 0;
if (fin >> next) {
highest = next;
} else {
cout << "Error: no data!\n";
exit(-1);
}
bool more = true;
while (more) {
fin >> next;
if (fin.fail()) {
more = false;
} else if (next > highest) {
highest = next;
}
}
cout << "Highest value: " << highest << endl;
fin.close();
return 0;
}
|
^ top
10.2.4: Reading File Data into a Vector
- Sometimes you want to process the data in a file several times
- One way to do this is to load the data into a vector
- Then you can process the data as a list
- 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
|
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
int main() {
ifstream fin("infile.txt");
if (fin.fail()) {
cout << "Input file failed to open.\n";
exit(-1);
}
// Load data into a vector
vector<int> data;
int value;
while(fin >> value) {
cout << "Read: " << value << endl;
data.push_back(value);
}
fin.close();
// Process vector data
double sum = 0;
int count = data.size();
for (int i = 0; i < count; i++) {
sum = sum + data[i];
}
cout << "average = " << (sum / count) << endl;
return 0;
}
|
^ top
10.2.5: Reading Files using getline()
- Recall that you can read text using a loop and an input stream like
fin:
int count = 0;
string word;
while (fin >> word) {
count++;
}
cout << count << " words.\n";
- However, just like with
cin, there are complications when you want to read words with spaces between them
>> skips whitespace and stops on encountering more whitespace
- Thus, you only get a single word for each input variable
- If you want to read a complete line of text like
"Hello Mom!", you need to use getline()
- For example:
ifstream fin;
// ... more code here
string line;
getline(fin, line);
cout << "Read data: " << line << endl;
- Recall that
getline() stops reading when it encounters a '\n'
- By contrast,
fin >> variable operates as follows:
- Skips whitespace
- Reads characters
- Stops reading when whitespace is found
- Thus if you mix
fin >> variable followed by getline(fin, line), you get mysterious results
- Just like with
cin, you get around this problem you by either:
- Only use
getline() before using fin (and never after using fin)
- Use
fin >> ws; before using getline()
^ top
10.2.6: Using Loops with getline()
Example Program Reading a File Using getline() in a Loop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#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);
}
string line;
int count = 1;
while(getline(fin, line)) {
cout << "Line " << count << ": "
<< line << endl;
count++;
}
fin.close();
return 0;
}
|
^ top
Exercise 10.2
In this exercise we explore reading all the lines of a file using a loop.
Specifications
- Copy the following program into a text editor, save it as
readwrite.cpp, and then compile and run the starter program to make sure you copied it correctly.
#include <fstream> // for file I/O
#include <iostream>
using namespace std;
int main() {
// Enter code here
return 0;
}
- Save the file rawdata.txt to the same directory as your program source code.
We will read from this file after writing our program.
- In
main(), add code to declare an input stream named fin and to connect the stream to the input file. In addition, make sure you use open() and check for failure.
For more information see section 10.1.6: Procedure For File I/O.
- In
main(), declare a vector of type double named data.
For more information see lesson 9.1.2: Defining Vectors.
- Add code to read all the values from the input file using a loop, print each input value to the screen, and save the input values in the vector.
For more information see section 10.2.4: Reading File Data into a Vector.
- Add the following code to sum the input data and calculate the average:
double sum = 0;
int count = data.size();
for (int i = 0; i < count; i++) {
sum = sum + data[i];
}
double average = sum / count;
cout << "average = " << average << endl;
- Compile and run your program and verify the screen output looks like:
Read: 12.34
Read: -9.87654
Read: 2.3131
Read: -89.506
Read: 12.3333
Read: 92.8765
Read: -123.457
average = -14.7109
If there are any problems, compare your source code to the listing below.
- After calculating the average, add code to declare an output stream named
fout and to connect the stream to an output file named output.txt. In addition, make sure you use open() and check for failure.
For more information see section 10.1.6: Procedure For File I/O.
- Add the following code to write the vector data and average to the output stream:
for (int i = 0; i < count; i++) {
fout << data[i] << endl;
}
fout << "average = " << average << endl;
fout.close();
- Open the output file you created and verify the vector data and average were written to the file. Your output file should look like:
12.34
-9.87654
2.3131
-89.506
12.3333
92.8765
-123.457
average = -14.7109
If there are any problems, compare your source code to the listing below.
- Submit your program source code to Blackboard as part of assignment 10.
Listing of readwrite.cpp

Check Yourself
As time permits, be prepared to answer these questions. You can find more information by following the links after the question.
- After opening a stream named
fin, what code will read the first item in the file into the variable named first? (10.2.1)
- What control-flow statement do you use to read every number in a file when you do not know how many numbers are in the file? (10.2.2)
- What is a loop condition you can use to read every number in a file? (10.2.2)
- What is the advantage of using a boolean variable to control a loop reading from a file? (10.2.3)
- What is the advantage of reading file data into a vector? (10.2.4)
- How do you code a statement to read a string from a file that includes spaces? (10.2.5)
- What function do you use to clear the input buffer after reading with
fin >> and before using getline()? (10.2.5)
- What is a loop condition you can use to read every line in a file? (10.2.6)
^ top
10.2.7: Summary
- You can use the extraction operator to read data from a file:
ifstream fin;
// ... more code here
double num;
fin >> num;
cout << "Read data: " << num << endl;
- The variable
fin is a stream operator and works just like cin
- Similarly, you use the
getline() function to read complete lines of text with spaces between words:
ifstream fin;
// ... more code here
string line;
getline(fin, line);
cout << "Read data: " << line << endl;
- 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 >> next) {
// process input
}
- Another way is to use a boolean variable to control the loop:
bool more = true;
while (more) {
fin >> next;
if (fin.fail()) {
more = false;
} else {
// process input
}
}
- We can read entire lines in a loop as well:
while(getline(fin, line)) {
// process input
}
- In addition, we can read file data into vectors or arrays
^ top
10.3: More I/O Topics
Learner Outcomes
At the end of the lesson the student will be able to:
- Append data to files
- Code user input as file names
- Code stream parameters in functions
|
^ top
10.3.1: Alternative Syntax for Open
- It is possible to construct a stream and open a file in one step
- Rather than:
ofstream fout;
fout.open("messages.txt");
if (fout.fail()) {
cout << "Output file opening failed.\n";
exit(-1);
}
- You can use:
ofstream fout("messages.txt");
if (fout.fail()) {
cout << "Output file opening failed.\n";
exit(-1);
}
^ top
10.3.2: Appending to a File
Example Appending 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
|
#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
10.3.3: File Names as Strings
- Note that the argument to
open() is a string:
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
Example Using a string for File Names
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() {
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;
}
fin.close();
return 0;
}
|
About C-strings
- C++ offers a special kind of
char array known as a C-string
- A C-string is a hold over from the C programming language
- However, many library functions still use C-strings and not
string variables
- Thus we need to convert
string variables to C-strings in these cases
- For more information see lesson 9.3.4: Character Arrays
^ top
10.3.4: Stream Parameters
Example Using Stream Parameters
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
|
#include <fstream>
#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) {
aStream << line << endl;
}
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);
}
fin.close();
fout.close();
return 0;
}
|
^ top
10.3.5: Reading File Data into a Vector of Objects
Example Reading a File into a Vector of Objects
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
class Product {
public:
Product();
Product(string newName, double newPrice);
void read(ifstream& fin);
void print() const;
private:
string name;
double price;
};
Product::Product() {
name = "Unknown";
price = 0.0;
}
Product::Product(string newName, double newPrice) {
name = newName;
price = newPrice;
if (price < 0) {
cout << "Error: negative price!\n"
<< "Setting price to 0.\n";
price = 0;
}
}
void Product::print() const {
cout << name << " @ " << price << endl;
}
void Product::read(ifstream& fin) {
fin >> name;
fin >> price;
}
// Read from filename into the vector
void readFile(vector<Product>& list, string filename);
// Display vector data
void listProducts(const vector<Product>& list);
int main() {
vector<Product> list;
readFile(list, "products.txt");
cout << "\nProducts in my store:\n";
listProducts(list);
return 0;
}
void readFile(vector<Product>& list, string filename) {
ifstream fin(filename.c_str());
if (fin.fail()) {
cout << "Input file failed to open.\n";
exit(-1);
}
while(fin.good()) {
Product temp;
temp.read(fin);
if (fin.good()) {
list.push_back(temp);
}
}
fin.close();
}
void listProducts(const vector<Product>& list) {
for (unsigned i = 0; i < list.size(); i++) {
Product temp = list[i];
temp.print();
}
}
|
^ top
10.3.6: Converting Between Strings and Numbers
Example Using String Streams to Convert Between Strings and Numbers
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
|
#include <sstream>
#include <iostream>
using namespace std;
/**
Convert a string to a double.
*/
double stringToDouble(string s) {
istringstream instr(s);
double number;
instr >> number;
return number;
}
/**
Convert a double to a string.
*/
string doubleToString(double num) {
ostringstream outstr;
outstr << num;
return outstr.str();
}
int main() {
string str = "123.4567";
double x = stringToDouble(str);
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
cout << "Numerical value: " << x * 2 << endl;
string strVal = doubleToString(x * 2);
string msg = "String value: " + strVal + "\n";
cout << msg;
return 0;
}
|
^ top
10.3.7: Other File Operations
- Some file operations are not supported by C++ streams
- In these cases, you use the C-style functions
- These functions are part of the
cstdio library:
#include <cstdio>
- This library is automatically included in our compiler
- 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("clear"); // clear the screen
system("cmd.exe /c color 1E"); // change colors
Changing Console Colors
- Since we are running Cygwin on Windows, we can use Windows to change the console colors
- The Windows command function is a program named
cmd
- You can set the console colors using the COLOR command using:
system("cmd.exe /c color attr");
- Where attr is TWO hex digits
- The first specifies the background
- The second specifies the foreground
- Each digit can be any of the following values:
0 = Black 8 = Gray
1 = Blue 9 = Light Blue
2 = Green A = Light Green
3 = Aqua B = Light Aqua
4 = Red C = Light Red
5 = Purple D = Light Purple
6 = Yellow E = Light Yellow
7 = White F = Bright White
^ top
Exercise 10.3
In this exercise we explore passing an input stream to a function.
Specifications
- Copy the following program into a text editor, save it as
showfile.cpp, and then compile and run the starter program to make sure you copied it correctly.
#include <fstream> // for file I/O
#include <iostream>
using namespace std;
void toScreen(ifstream& fin);
int main() {
string filename, line;
cout << "Enter a file name: ";
cin >> filename;
// Start adding code here
return 0;
}
// Add new function toScreen() here
- In
main(), add code to declare an input stream named fin and to connect the stream to the input file entered by the user into the string variable filename. In addition, make sure you check for failure.
For more information see section 10.3.3: File Names as Strings.
- Using the function prototype shown in the starter code, write the definition of the
toScreen() function.
The toScreen() function reads one line at a time from the input stream parameter using function getline(). Then the function displays the count of each line and the line read to the screen using cout. For more information see section 10.2.6: Using Loops with getline().
- Call the
toScreen() function from main() using the input stream fin as an argument.
- Compile and run your program and verify the screen output looks like:
Enter a file name: showfile.cpp
1: #include <fstream> // for file I/O
2: #include <iostream>
3: using namespace std;
4:
5: void toScreen(ifstream& fin);
6:
7: int main() {
8: string filename, line;
9:
10: cout << "Enter a file name: ";
11: cin >> filename;
12: ifstream fin(filename.c_str());
13: if (fin.fail()) {
14: cout << "Input file failed to open.\n";
15: exit(-1);
16: }
17: toScreen(fin);
18: fin.close();
19:
20: return 0;
21: }
22:
23: void toScreen(ifstream& fin) {
24: string line;
25: int count = 1;
26: while(getline(fin, line)) {
27: cout << count << ": " << line << endl;
28: count++;
29: }
30: }
Notice that the file name entered by the user in this example was showfile.cpp. Thus you can use this listing to compare your work if you have problems.
- Submit your program source code to Blackboard as part of assignment 10.
Check Yourself
As time permits, be prepared to answer these questions. You can find more information by following the links after the question.
- How can you construct and open a file stream in one statement? (10.3.1)
- How do you keep a file opened for writing from destroying existing information? (10.3.2)
- What string function do you use to convert a
string to a C-string? (10.3.3)
- How do you code streams as parameters for a function? (10.3.4)
- How can you read data from a file into an object before inserting it into a vector? (10.3.5)
- Using string streams, you can read from and write to strings rather than files. Why is this useful? (10.3.6)
- To delete the file named "error.log", what statement would you write? (10.3.7)
- To change the name of the file named "error.log" to "error.bak", what statement would you write? (10.3.7)
^ top
10.3.8: Summary
- You can construct a stream and open it in one step:
ofstream fout("messages.txt");
- 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);
- You can use
string variables as the names of files
- However, we must use the
c_str() function to convert to a C-string:
ifstream fin(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
- You can read or write to strings, rather than files, using string streams
- This is useful for converting between numbers and strings
- Using an
istringstream, we can read numbers that are stored in a string by using the >> operator
- Similarly, by writing to an
ostringstream, we can convert numbers to strings using the << operator
- We developed some helper functions to support these conversions
- In addition, we discussed file operations for removing and renaming files
^ top
10.4: Formatting Output
Learner Outcomes
At the end of the lesson the student will be able to:
- Write code using output formatting functions
- Write code using manipulators
|
^ top
10.4.1: Formatting Functions
- Formatting functions are used to set the layout of the output
- We have used formatting functions before with the "magic formula":
cout.setf(ios::fixed); // fixed notation, not scientific
cout.setf(ios::showpoint); // show decimal point
cout.precision(2); // show 2 decimal places
- However, there are many more formatting functions available
- Remember that formatting functions do not affect the value of any variables
- Also, note that these same functions apply to all output streams including
cout
- Function 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::left); // Left justify
fout.setf(ios::right); // Right justify
- Note how
(ios::left) and (ios::right) operate:

- Function unsetf() clears a format flag:
fout.unsetf(ios::showpos); // No more + signs
- Function precision() sets the number of digits to display for floating-point numbers:
fout.precision(2); // show 2 decimal digits
- Note that if the
fixed or scientific flag is set, then precision() controls the digits to the right of the decimal point
- If neither the
fixed or scientific flag is set, then precision() controls the total digits
- Function width() sets or returns 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.width(3);
fout << 123.45 << endl; // ouputs 123.45
- The following program uses formatting functions to provide neatly formatted output
- Note that the formatting functions work with both
cout and the ofstream fout
Example Formatting Output
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;
}
|
More Information
- Format flags: arguments for
setf() and unsetf() from cppreference.com
^ top
10.4.2: Manipulators
- Another way to format output is to use a manipulator
- Manipulator: a function called in a nontraditional way
- We have use manipulators before:
endl
- Other manipulators include:
fout << fixed; // Fixed notation
fout << scientific; // Scientific notation
fout << showpoint; // show decimal point
fout << showpos; // Show + signs
fout << left; // Left justify
fout << right; // Right justify
- Most manipulators are part of the
<iostream> library
- To use some manipulators you need to include:
#include <iomanip>
- Some manipulators may require arguments
setw(): sets the field width for the next output:
cout << "Start" << setw(4) << 10 << setw(6) << 20;
setprecision(): sets the number of digits to display for floating-point numbers:
cout << "$" << setprecision(2) << 10.4 << endl;
- Note that if the
fixed or scientific flag is set, then setprecision() controls the digits to the right of the decimal point
- If neither the
fixed or scientific flag is set, then setprecision() controls the total digits
- For comparison, the equivalent of the "magic formula" using manipulators is:
cout << fixed << showpoint << setprecision(2);
- The following program uses several manipulators to provide neatly formatted output
- Note that the manipulators work with both
cout and the ofstream fout
Example Using Manipulators for Formatting
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;
}
|
Input Manipulator
More Information
^ top
10.4.3: Example of Formatting Data
Example Application to Make Messy Data Neat
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
Exercise 10.4
In this exercise we explore how to format output.
Specifications
- Create a text file named
formatting.txt
- Complete the following and record the answers to the questions in the file.
- Run the following code and answer the question:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << "*";
cout.width(5);
cout << 123
<< "*" << 123 << "*" << endl;
cout << "*" << setw(5) << 123
<< "*" << 123 << "*" << endl;
return 0;
}
Q1: To how many numeric fields does width() or setw() formatting functions apply?
- Run the following code and answer the question:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
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 and answer the question:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << "*" << setw(3) << 12345 << "*\n";
return 0;
}
Q3: How many digits are displayed? Why?
- Run the following code and answer the question:
#include <iostream>
using namespace std;
int main() {
cout << "Enter your age: ";
int age;
cin >> age;
cout << "Enter your full name: ";
string name;
getline(cin, name);
cout << "Your age: " << age << endl
<< "Your full name: " << name << endl;
}
Q4: What is the problem with this code?
- To the above program, add the following code before the call to
getline(), rerun the code and answer the questions:
cin >> ws; // clear whitespace from buffer
Q5: Why did this line fix the problem?
Q6: How does this fix compare to using cin.ignore()?
- Submit your
formatting.txt file to Blackboard as part of assignment 10.
Check Yourself
As time permits, be prepared to answer these questions.
- How do you set the width of a field when outputting numbers using and output stream like
cout? (10.4.1)
- After you set the width of a numeric field, how long does the setting last? (10.4.1)
- If the number you display needs more digits than the specified width, does the entire number get displayed? (10.4.1)
- By default, is numerical output left or right justified? (10.4.1)
- What is meant by the term manipulator? (10.4.2)
- How do you set the width of a field when outputting numbers using a manipulator? (10.4.2)
- What is the "magic formula" for decimal formatting using manipulators? (10.4.2)
^ top
10.4.4: Summary
- C++ has many formatting functions to set the layout of the output
- We have used formatting functions before with the magic formula for decimal formatting:
cout.setf(ios::fixed); // fixed notation, not scientific
cout.setf(ios::showpoint); // show decimal point
cout.precision(2); // show 2 decimal places
- However, there are many more formatting functions and we explored how to use more of them
- You can use these functions with
cout and ofstream types
- You can use manipulators to change formatting within the stream
- Manipulators perform the same type of operations as formatting functions but are included in the output stream
- For example:
cout << "$" << setprecision(2) << 10.4 << endl;
^ top
Wrap Up
Due Next: A9-Keeping Lists (4/29/10)
A10-Storing Information (5/6/10)
- When class is over, please shut down your computer
- You may complete unfinished exercises at the end of the class or at any time before the next class.
^ top
Home
| Blackboard
| Day Schedule
| Eve Schedule
Syllabus
| Help
| FAQ's
| HowTo's
| Links
Last Updated: February 06 2010 @16:38:36
|