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

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




Console input (standard input)


Console output (standard output)


Console error (standard error)


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 <

runs the program my_prog and assigns std::cin to the file

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:"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"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 


  • 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

  • On-demand Event Event Date: October 29, 2014 It's well understood how critical version control is for code. However, its importance to DevOps isn't always recognized. The 2014 DevOps Survey of Practice shows that one of the key predictors of DevOps success is putting all production environment artifacts into version control. In this webcast, Gene Kim discusses these survey findings and shares woeful tales of artifact management gone wrong! Gene also shares examples of how high-performing DevOps …

  • On-demand Event Event Date: December 18, 2014 The Internet of Things (IoT) incorporates physical devices into business processes using predictive analytics. While it relies heavily on existing Internet technologies, it differs by including physical devices, specialized protocols, physical analytics, and a unique partner network. To capture the real business value of IoT, the industry must move beyond customized projects to general patterns and platforms. Check out this webcast and join industry experts as …

Most Popular Programming Stories

More for Developers

RSS Feeds