There may be times when you want to modify the way a file is opened or used in a program. For example, in some cases it is desirable that writes append to the end of a file rather than overwriting the existing values. The file stream constructor takes a second argument, the open mode, that allows such variations to be specified. Here is an example that creates a file stream object Str, connects it to the external file named "inout.txt", and opens it for reading and for writing at the end of the file:
std::fstream Str("inout.txt", std::ios_base::in | std::ios_base::out | std::ios_base::app);
Note that if the "inout.txt" file doesn't exist it will be created.
The open mode argument is of type std::ios_base::openmode, which is a bitmask type like the format flags and the stream state. Table 32 defines the following bits:
Flag Names | Effects |
ios_base::in | Open file for reading |
ios_base::out | Open file for writing |
ios_base::ate | Start position is at file end |
ios_base::app | Append file; that is, always write to the end of the file |
ios_base::trunc | Truncate file; that is, delete file content |
ios_base::binary | Binary mode |
Input (and output) file streams always have the in (or out) open mode flag set implicitly. An output file stream, for instance, knows that it is in output mode and you need not set the output mode explicitly. Instead of writing:
std::ofstream Str("out.txt", std::ios_base::out | std::ios_base::app);
you can simply say:
std::ofstream Str("out.txt", std::ios_base::app);
Bidirectional file streams, on the other hand, do not have the flag set implicitly. This is because a bidirectional stream does not have to be in both input and output mode in all cases. You might want to open a bidirectional stream for reading only or writing only. Bidirectional file streams therefore have no implicit input or output mode. You must always set a bidirectional file stream's open mode explicitly.
Each file maintains a single file position that indicates the position in the file where the next byte will be read or written. When a file is opened, the initial file position is usually at the beginning of the file. The open modes std::ios_base::ate (meaning at end) and std::ios_base::app (meaning append) change this default to the end of the file.
There is a subtle difference between ate and app mode. If the file is opened in append mode, all output to the file is done at the current end of the file, regardless of intervening repositioning. Even if you modify the file position to a position before the file's end, you cannot write there. With ate mode, you can navigate to a position before the end of file and write to it.
If you open an already existing file for writing, you usually want to overwrite the content of the output file. The open mode std::ios_base::trunc (meaning truncate) has the effect of discarding the file content, in which case the initial file length is set to 0. Therefore, if you want to replace a file's content rather than extend the file, you must open the file in std::ios_base::out | std::ios_base::trunc. Note that the file position is at the beginning of the file in this case, which is exactly what you expect for overwriting an output file.
NOTE -- For output file streams the open mode out is equivalent to out|trunc, that is, you can omit the trunc flag. For bidirectional file streams, however, trunc must always be explicitly specified.
If you want to extend an output file, you open it with the bitwise or of std::ios_base::ate and std::ios_base::app mode. In this case, the file content is retained because the trunc flag is not set, and the initial file position is at the file's end. However, you may additionally set the trunc flag; the file content is discarded and the output is done at the end of an empty file.
Input mode only works for files that already exist. Otherwise, the stream construction fails, as indicated by failbit set in the stream state. Files that are opened for writing are created if they do not yet exist. The constructor only fails if the file cannot be created.
The std::ios_base::binary open mode is discussed in Section 30.4.
The effect of combining these open modes is similar to the mode argument of the C library function fopen(name,mode). Table 33 gives an overview of all permitted combinations of open modes for text files and their counterparts in C stdio. Combinations of modes that are not listed in the table (such as both trunc and app) are invalid, and the attempted open() operation fails.
Open Mode | C stdio Equivalent | Effect |
in | "r" | Open text file for reading only |
out|trunc out | "w" | Truncate to 0 length, if existent, or create text file for writing only |
out|app | "a" | Append; open or create text file only for writing at end of file |
in|out | "r+" | Open text file for update (reading and writing) |
in|out|trunc | "w+" | Truncate to 0 length, if existent, or create text file for update |
in|out|app | "a+" | Append; open or create text file for update, writing at end of file |
The open mode parameter in constructors and open() functions of file stream classes have a default value. The default open modes are listed in Table 34.
File Stream | Default Open Mode |
ifstream | in |
ofstream | out |
fstream | in|out |