NULL
By Steve Oualline
http://www.oreilly.com/catalog/cplus2/?CMP=OT16470
O'Reilly & Associates, December 2002
ISBN: 0-596-00419-2
Chapter 16: File Input/Output
I am the heir of all the ages, in the foremost files of time.
--Tennyson
A file is a collection of related data. C++ treats a file as a series of bytes. Many files reside on disk; however, devices such as printers, magnetic tapes, and communication lines are also considered files.
This chapter discusses three different I/O packages. The first is the C++ I/O stream classes. This is the most commonly used I/O system and the one we've been using up to now. Next, we examine the raw I/O routines that give us direct access to the low-level I/O. Finally we look at the C I/O system. Although it is somewhat outdated, C I/O calls still appear in old code. Also, in some cases, the C-style I/O routines are superior to the ones provided with C++.
C++ File I/O
C++ file I/O is based on three classes: the istream class for input, the ostream class for output, and the iostream class for input/output. C++ refers to files as streams since it considers them a stream of bytes. Four class variables are automatically created when you start a program. These are listed in Table 16-1.
|
Variable |
Use |
|---|---|
|
cin |
Console input (standard input) |
|
cout |
Console output (standard output) |
|
cerr |
Console error (standard error) |
|
clog |
Console log |
These variables are defined in the standard include file <iostream>. Normally, std::cin is assigned to the keyboard and std::cout, std::cerr, and std::clog are assigned to the screen. Most operating systems allow you to change these assignments through I/O redirection (see your operating system manual for details).
For example, the command:
my_prog <file.in
runs the program my_prog and assigns std::cin to the file file.in.
When doing I/O to disk files (except through redirection), you must use the file version of the stream classes. These are std::ifstream, std::ofstream, and std::fstream and are defined in the include file <fstream>.
Suppose you want to read a series of 100 numbers from the file numbers.dat. You start by declaring the input file variable:
std::ifstream data_file; // File we are reading the data from
Next you need to tell C++ what disk file to use. This is done through the open member function:
data_file.open("numbers.dat");
Now you can read the file using the same statements you've been using to read std::cin:
for (i = 0; i < 100; ++i) {assert(i >= 0);assert(i < sizeof(data_array)/sizeof(data_array[0]));data_file >> data_array[i];}
Finally you need to tell the I/O system that you are done with the file:
data_file.close( );
Closing the file frees resources that can then be used again by the program.
C++ allows the open call to be combined with the constructor. For example, instead of writing:
std::ifstream data_file; // File we are reading the data fromdata_file.open("numbers.dat");
you can write:
std::ifstream data_file("numbers.dat"); // File we are reading the data from
Additionally, the destructor automatically calls close.
But what if the file numbers.dat is missing? How can you tell if there is a problem? The member function bad returns true if there is a problem, and false otherwise. So to test for problems, all you need is:
if (data_file.bad( )) {std::cerr << "Unable to open numbers.dat\n";exit (8);}
A better version of the program for reading numbers is listed in Example 16-1.
Example 16-1: read/read.cpp
/********************************************************* read -- read in 100 numbers and sum them ** ** Usage: ** read ** ** Numbers are in the file "numbers.dat" ** ** Warning: No check is made for a file with less than ** 100 numbers in it. *********************************************************/#include <iostream>#include <fstream>#include <cstdlib>int main( ){const int DATA_SIZE = 100; // Number of items in the dataint data_array[DATA_SIZE]; // The datastd::ifstream data_file("numbers.dat"); // The input fileint i; // Loop counterif (data_file.bad( )) {std::cerr << "Error: Could not open numbers.dat\n";exit (8);}for (i = 0; i < DATA_SIZE; ++i) {assert(i >= 0);assert(i < sizeof(data_array)/sizeof(data_array[0]));data_file >> data_array[i];}int total; // Total of the numberstotal = 0;for (i = 0; i < DATA_SIZE; ++i) {assert(i >= 0);assert(i < sizeof(data_array)/sizeof(data_array[0]));total += data_array[i];}std::cout << "Total of all the numbers is " << total << '\n';return (0);}
If you want to read a line of data, you need to use the getline function. It is defined as:[1]
std::istream& getline(std::istream& input_file,std::string& the_string);std::istream& getline(std::istream& input_file,std::string& the_string, char delim)
This function reads a line and stores it in a string. The function returns a reference to the input stream. The second form of the function allows you to specify your own end-of-line delimiter. If this is not specified, it defaults to newline ('\n').

Comments
There are no comments yet. Be the first to comment!