NULL

Practical C++ Programming, 2nd Edition
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.

Table 16-1: Predefined I/O class variables

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 from
data_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 data
    int data_array[DATA_SIZE];  // The data
    std::ifstream data_file("numbers.dat"); // The input file
    int i;                      // Loop counter
 
    if (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 numbers
 
    total = 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').

Page:  1   2   3   4   5   6   7   8   9   Next 



Comments

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

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Savvy enterprises are discovering that the cloud holds the power to transform IT processes and support business objectives. IT departments can use the cloud to redefine the continuum of development and operations—a process that is becoming known as DevOps. Download the Executive Brief DevOps: Why IT Operations Managers Should Care About the Cloud—prepared by Frost & Sullivan and sponsored by IBM—to learn how IBM SmartCloud Application services provide a robust platform that streamlines …

  • Mobile is introducing sweeping changes throughout your workplace. As a senior stakeholder driving mobile initiatives in your organization, you may be lost in a sea of technologies and claims from vendors promising rapid delivery of applications to your employees, customers, and partners. To help explain some of the topics you will need to be aware of, and to separate the must-haves from the nice-to-haves, this reference guide can help you with applying a mobile strategy in the context of application …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds