Programming in C++ with the Streams Library - dummies

Programming in C++ with the Streams Library

By John Paul Mueller, Jeff Cogswell

The ANSI C++ standard document gives a complete library of classes that handle streams and general input/output. Fortunately, most of the classes in the Standard Library are available with almost all the compilers currently available.

Getting the right header file

The streams library includes several classes that make your life much easier. It also has several classes that can make your life more complicated, mainly because these are auxiliary classes that you’ll probably rarely use. Here are two of the more common classes that you will use. (And remember: These classes are available in pretty much all C++ implementations, whether the complete Standard Library is present or not.)

  • ifstream: This is a stream you instantiate if you want to read from a file.

  • ofstream: This is a stream you instantiate if you want to write to a file.

Before you can use the ifstream and ofstream classes, you include the proper header file. This is where things get ugly. In the early days of C++, people used the header file <fstream.h>. But somewhere in the mid-1990s, people started using the Standard Template Library (and in the late 1990s, the Standard C++ Library), both of which required you to include <fstream> (without the .h extension).

The Standard Template Library and the Standard Library put all their classes and objects inside the std namespace. Thus, when you want to use an item from the streams library, you must either

  • Prepend its name with std, as in this example:

    std::ofstream outfile("MyFile.txt");
  • Include a using directive before the lines where you use the stream classes, as in this example:

using namespace std;
ofstream outfile("MyFile.txt");

By default, the GCC compiler automatically recognizes the std namespace (it’s as if you had a line using namespace std; even when you don’t).

If you’re using a compiler other than GCC, follow your #include lines with the line using namespacestd;. Then you can type all the sample code as-is, including the stream examples, without needing to put std:: before every class or object from the Standard Library.

Opening a file

Go to the word processor, choose File→Open, and type MyGreatChapter.doc.

Oops. You get an error message. That file doesn’t exist.

Oh, that’s right; you haven’t written it yet. Instead, create a new document inside the word processor, type 800 cool pages over the course of a relaxing evening, and then (when you’re all finished) save the file. Give it the name MyGreatChapter.doc. Then shut down the word processor, hang out by the pool, brag to your friends about the new novels you’re writing, and go to bed.

The next morning, open the document. This time it exists, so the word processor opens it and reads in the information.

As you can see, two issues present themselves in opening a file:

  • Create a new file

  • Open an existing file

Here’s where life gets a little strange: Some operating systems treat these two items as a single entity. The reason is that when you create a new file, normally you want to immediately start using it, which means you want to create a new file and then open it. And so the process of creating a file is often embedded right into the process of opening a file.

And when you open an existing file that you want to write to, you have two choices:

  • Erase the current contents; then write to the file.

  • Keep the existing contents and write your information to the end of the file. This is called appending information to a file.

The FileOutput01 example code shows you how to open a brand-new file, write some information to it, and then close it. (But wait, there’s more: This version works whether you have the newer ANSI-compliant compilers or the older ones!)

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    ofstream outfile("../MyFile.txt");
    outfile << "Hi" << endl;
    outfile.close();
    return 0;
}

The short application opens a file called MyFile.txt. (The “../” part of the file path places the file in the parent directory for the example, which is the Chapter01 folder.) It does this by creating a new instance of ofstream, which is a class for writing to a file.

The next line of code writes the string “Hi” to the file. It uses the insertion operator, >>, just as cout does. In fact, ofstream is derived from the very class that cout is an instance of, and so that means all the things you can do with cout you can also do with your file! Wow!

When you’re finished writing to the file, close it by calling the close member function. This is important!

If you want to open an existing file and append to it, you can modify the listing slightly. All you do is change the arguments passed to the constructor as follows:

ofstream outfile("MyFile.txt", ios_base::app);

The ios::app item is an enumeration inside a class called ios, and the ios_base::app item is an enumeration in the class called ios_base.

The ios class is the base class from which the ofstream class is derived. The ios class also serves as a base class for ifstream, which is for reading files.

For newer compilers, the ios_base class is a base for ofstream and ifstream. (A couple of classes are in between. ofstream is a template class derived from a template class called basic_ofstream, which is derived from a template class called basic_ios, which is derived from the class ios_base.)

You can also read from an existing file. This works just like the cin object. The FileRead01 example shown opens the file created earlier and reads the string back in. This example uses the parent directory again as a common place to create, update, and read files.

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
    string word;
    ifstream infile("../MyFile.txt");
    infile >> word;
    cout << word << endl;
    infile.close();
    return 0;
}

When you run this application, the string written earlier to the file — “Hi,” — appears onscreen. It worked! It read the string in from the file!