|
|
The classes ofstream and ifstream are derived from ostream and istream and inherit the insertion and extraction operations respectively. In addition they contain members and constructors that deal with files. The examples in this subtopic assume that the header file fstream.h has been included.
If the program wants to read or write a particular file it can do so by declaring an ifstream or ofstream respectively. For example,
ifstream source("from") ;
if ( !source ) error("unable to open 'from' for input");
ofstream target("to") ;
if ( !target ) error("unable to open 'to' for output");
char c ;
while ( target && source.get(c) ) target.put(c) ;
copies the file
from
to the file
to.
If the
ifstream()
or
ofstream()
constructor is unable to open a
file in the requested mode it indicates this in the error state of the
stream.
In some circumstances a program may wish to declare a file stream without specifying a file. This may be done and the filename supplied later. For example:
ifstream file ; ... ; file.open(argv[1]) ;
It is even possible to reuse the same variable by closing it between calls to open(). For example:
ifstream infile ;
for ( char** f = &argv[1] ; *f ; ++f ) {
infile.open(*f) ;
... ;
infile.close() ;
}
In some circumstances the program may already have a file descriptor (such as the integer 0 for standard input) and want to use a file stream. For example,
ifstream infile ; if ( strcmp(argv[1],"-") ) infile.open(argv[1],input) ; else infile.attach(0) ;opens infile to read a file named by argv[1], unless the name is -. In that case it will connect infile with the standard input (file descriptor 0). A subtle point is that closing a file stream (either explicitly or implicitly in the destructor) will close the underlying file descriptor if it was opened with a filename, but not if it was supplied with attach.
Sometimes the program wants to modify the way in which the file is opened or used. For example, in some cases it is desirable that writes append to the end of a file rather than rewriting the previous values. The file stream constructors take a second argument that allows such variations to be specified. For example,
ofstream outfile("out",ios::app|ios::nocreate) ;
declares
outfile
and attempts to attach it to a file named
out.
Because
ios::app
is specified all writes will append to the file.
Because
ios::nocreate
is specified the file will not be created.
That is, the open will fail (indicated in
outfile's
error status)
if the file does not previously exist.
The enum
open_mode
is declared in
ios.
class ios {
enum open_mode { in, out, app, ate, nocreate, noreplace } ;
};
These modes are each individual bits and may be or'ed together.
Their detailed meanings are described in the man pages.
Sometimes it is desirable to use the same file for both input and output. fstream is an iostream (a class derived via multiple inheritance from both istream and ostream). The type streampos is used for positions in an iostream. For example,
fstream tmp("tmp",ios::in|ios::out) ;
...
streampos p = tmp.tellp() ; // tellp() returns current position
tmp << x ;
...
tmp.seekg(p) ; // seekg() repositions iostream
tmp >> x ;
saves the position of the file in
p,
writes
x
to it, and later
returns to the same position to restore the value of
x.
A variant of seekg() takes a streamoff (integral value) and a seek_dir to specify relative positioning. For example,
tmp.seekg(-10,ios::end) ;positions the file 10 bytes from the end, and
tmp.seekg(10,ios::cur) ;moves the file forward 10 bytes.