Each stream has an associated file mode that represents how the file may be used. Table 8.4 lists the file modes and their meanings.
We can supply a file mode whenever we open a file—either when we call open
or when we indirectly open the file when we initialize a stream from a file name. The modes that we can specify have the following restrictions:
• out
may be set only for an ofstream
or fstream
object.
• in
may be set only for an ifstream
or fstream
object.
• trunc
may be set only when out
is also specified.
• app
mode may be specified so long as trunc
is not. If app
is specified, the file is always opened in output mode, even if out
was not explicitly specified.
• By default, a file opened in out
mode is truncated even if we do not specify trunc
. To preserve the contents of a file opened with out
, either we must also specify app
, in which case we can write only at the end of the file, or we must also specify in
, in which case the file is open for both input and output (§ 17.5.3 (p. 763) will cover using the same file for input and output).
• The ate
and binary
modes may be specified on any file stream object type and in combination with any other file modes.
Each file stream type defines a default file mode that is used whenever we do not otherwise specify a mode. Files associated with an ifstream
are opened in in
mode; files associated with an ofstream
are opened in out
mode; and files associated with an fstream
are opened with both in
and out
modes.
out
Mode Discards Existing DataBy default, when we open an ofstream
, the contents of the file are discarded. The only way to prevent an ostream
from emptying the given file is to specify app
:
// file1 is truncated in each of these cases
ofstream out("file1"); // out and trunc are implicit
ofstream out2("file1", ofstream::out); // trunc is implicit
ofstream out3("file1", ofstream::out | ofstream::trunc);
// to preserve the file's contents, we must explicitly specify app mode
ofstream app("file2", ofstream::app); // out is implicit
ofstream app2("file2", ofstream::out | ofstream::app);
The only way to preserve the existing data in a file opened by an ofstream
is to specify app
or in
mode explicitly.
open
Is CalledThe file mode of a given stream may change each time a file is opened.
ofstream out; // no file mode is set
out.open("scratchpad"); // mode implicitly out and trunc
out.close(); // close out so we can use it for a different file
out.open("precious", ofstream::app); // mode is out and app
out.close();
The first call to open
does not specify an output mode explicitly; this file is implicitly opened in out
mode. As usual, out
implies trunc
. Therefore, the file named scratchpad
in the current directory will be truncated. When we open the file named precious
, we ask for append mode. Any data in the file remains, and all writes are done at the end of the file.
Any time open
is called, the file mode is set, either explicitly or implicitly. Whenever a mode is not specified, the default value is used.
Exercise 8.7: Revise the bookstore program from the previous section to write its output to a file. Pass the name of that file as a second argument to main
.
Exercise 8.8: Revise the program from the previous exercise to append its output to its given file. Run the program on the same output file at least twice to ensure that the data are preserved.