Click Here!
home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
[an error occurred while processing this directive]
Previous Table of Contents Next


CHAPTER 15
FILE I/O

How do I...

15.1  Open a file stream?
15.2  Continually read data until the end of file?
15.3  Handle stream errors?
15.4  Read and write binary files?
15.5  Read from or write to different positions in a file?

A great strength of C++ is that stream processing is identical whether the stream is a console, a file, or a memory area. This design was intentional, and along with the inheritance structure of the IOStreams library, allows code to be written independent of whether the target stream deals with a file, console, or memory area.

This chapter covers IOStreams with a focus on file streams because some issues affect them more visibly. It’s not that these issues don’t exist with the other streams, but rather that these features are most often used when dealing with files. For instance, cin does not need to deal with end-of-file notifications very often because consoles generally do not suddenly end. cin would have to account for this, however, if it were fed a redirected file through the shell (consult your operating system or shell manual for information on pipes and redirection).

15.1 Open a File Stream

Console streams cin and cout are defined automatically in your program. This How-To shows how to work with files in the same way, using the same techniques.

15.2 Continually Read Data Until the End of File

Some sample code in the previous chapter hinted at how this works. This How-To describes how to read data from a file without the last piece appearing twice and other pesky “off-by-one” errors.

15.3 Handle Stream Errors

Errors when handling file streams are much more common than when working with cout and cin. Most of the techniques here are useful when dealing with other streams as well, but are in highest demand when working with data files.

15.4 Read and Write Binary Files

Binary files are different to deal with than text files. The main reason is that the entire IOStreams library is based on converting from human-readable values to machine-readable ones. In this How-To, techniques to bypass this difficulty are discussed, and the advantages of doing so are also covered.

15.5 Read from or Write to Different Positions in a File

Binary data is mainly used for things that need to be accessed quickly, such as databases and other file types. Binary data also has the advantage of having a calculable size. This is ideal for retrieving records using random file access techniques.

15.1 Open a file stream?

Problem

There are lots of options when opening a file stream. What’s the best way to open one?

Technique

The IOStreams library provides two classes to handle file I/O for your programs. The thing to remember is that the streams cout, cerr, and cin are also technically file streams, as most operating systems treat consoles as regular files. Although this does not usually affect programs, it can be an important point if your program has its input or output redirected.

The Classes

The class that handles writing to a file is called ofstream. It is declared like a normal variable, and its most commonly used constructor looks like this:

ofstream::ofstream( const char* filename, int openmode = ios::out,
⇒int prot = filebuf::openprot);

The counterpart to read from a file is ifstream. Its constructor looks identical, but operates on different assumptions:

ifstream::ifstream( const char* filename, int openmode = ios::in ,
⇒int prot = filebuf::openprot);

Finally, there is the class that can both read and write to a file. Most C++ systems make this stream for input only by default. It’s an fstream, and its constructor looks like this:

fstream::fstream( const char* filename, int openmode = ios::in,
⇒int prot = filebuf::openprot);

filename is the name of the file you wish to open. Note that even on MS-DOS and related systems, the forward-slash character should be used for directory names, for example “c:/config.sys”. The reason is that the backslash character, when followed by certain characters, has special meaning in strings. For instance, the string “c:\newfile.txt” will not open that file; the \n sequence translates to a newline sequence. If your program does use the backslash character, denote that by using two backslashes, like “c:\\newfile”.

openmode is the stream mode, which is defined by the base of all IOStreams classes, ios. The default (which is probably correct for most uses) is ios::in, meaning that the stream should refuse to be written to. Additional values need to be bitwise ored together.

Options include the following:

  ios::app will seek to the end of file and assume to be ready to append. This really makes little sense for input streams.
  ios::ate will seek to the end of the file when it’s open. Again, this usually does not make sense for file streams that will be read from.
  ios::binary will open the stream in binary mode. This makes things somewhat different to work with, in that the stream is not parsed by whitespace anymore. This will be covered in a later How-To.
  ios::trunc will truncate a file if it exists. This is the default for opening files for writing if neither ios::app nor ios::ate is specified.
  ios::nocreate will cause the stream to fail if the file does not exist. This is implied in most ofstream implementations.
  ios::noreplace will cause the stream to fail if the file already exists. Use this if you don’t want to overwrite anything. This is implied with ifstreams.

The constructor’s prot argument is the file’s opening mode. Which modes are supported depends on your operating system (and therefore varies from compiler to compiler). The IOStreams library does its best to accommodate everybody, but systems are diverse, so your system might support modes that are not in the stock library. To find out more about the modes that your operating system and compiler support, look at the documentation for open() function in io.h. By default, all file streams classes open the file in read-write mode, without sharing.

Now that the constructors are covered, a few other things need to be explained:

  A file stream object can be reused by using the open and close member functions (note that these are different from the open and close discussed above). The open member function takes the same argument as the constructor, and close takes no arguments.
  File stream classes automatically close the file they are associated with when they fall out of scope.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.