December 18, 2014
Hot Topics:

C++ File Input/Output

  • March 20, 2003
  • By Steve Oualline
  • Send Email »
  • More Articles »

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 of 9

Comment and Contribute


(Maximum characters: 1200). You have characters left.



Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel