By Stephen R. Davis

This table shows the different modes in C++ that are possible when opening a file. However, you need to answer three basic questions every time you open a file:

  • Do you want to read from the file or write to the file? Use ifstream to read and ofstream for writing. If you intend to both write to and read from the same file, use the fstream and set mode to in|out, but good luck — it’s much better to write to a file completely and then close it and reopen it for reading as a separate object.

  • If you are writing to the file and it already exists, do you want to add to the existing contents (in which case, open with ate set) or truncate the file and start over (in which case use trunc)?

  • Are you reading or writing text or binary data? Both ifstream and ofstream default to text mode. Use binary mode if you are reading or writing raw, non-text data.

Constants that Control How Files Are Opened
Flag Meaning
ios_base::app Seek to end-of-file before each write.
ios_base::ate Seek to end-of-file immediately after opening the file, if it
ios_base::binary Open file in binary mode (alternative is text mode).
ios_base::in Open file for input (implied for istream).
ios_base::out Open file for output (implied for ostream).
ios_base::trunc Truncate file, if it exists (default for ostream).

The primary difference between binary and text mode lies in the way that newlines are handled. The Unix operating system was written in the days when typewriters were still fashionable (when it was called “typing” instead of “keyboarding”). Unix ended sentences with a linefeed followed by a carriage return.

Subsequent operating systems saw no reason to continue using two characters to end a sentence, but they couldn’t agree on which character to use. Some use the carriage return, others used the linefeed, now renamed newline. The C++ standard is the single newline.

When a file is opened in text mode, the C++ library converts the single newline character into what is appropriate for your operating system on output, whether it’s a carriage return plus linefeed, a single carriage return, a linefeed, or something else entirely. It performs the opposite conversion while reading a file. The C++ library does no such conversions for a file opened in binary mode.

Always use binary mode when manipulating a file that’s not in human-readable format. Otherwise, if a byte in the data stream just happens to be the same as a carriage return or a linefeed, the file I/O library will modify it.