Apologies for the partial overlap with other answers, but for the sake of completeness:
Myth: endl
is 'more portable' since it writes the line ending depending on the platform convention.
Truth: endl
is defined to write \n
to the stream and then call flush
. So in fact you almost never want to use it. All \n
that are written to a text-mode stream are implicitly converted to \r\n
by the CRT behind the scenes, whether you use os<<endl
, os<<'\n'
, or fputs("\n",file)
.
Myth: You should open files in text mode to write text and in binary mode to write binary data.
Truth: Text mode exists in the first place because some time ago there were file-systems that distinguished between text files and binary files. It's no longer true on any sane platform I know. You can write text to binary-opened files just as well, you just loose the automatic \n
-> \r\n
conversion on Windows. However, this conversion causes more harm than good. Among others, it makes your code behave differently on different platforms, and tell/seek
become problematic to use. Therefore it's best to avoid this automatic conversion. Note that POSIX does not distinguish between binary and text mode.
How to do text: Open everything in binary mode and use the plain-old \n
. You'll also need to worry about the encoding. Standardize on UTF-8 for Unicode-correctness. Use UTF-8 encoded narrow-strings internally, instead of wchar_t
which is different on different platforms. Your code will become easier to port.
Tip: You can force MSVC to open all files in binary mode by default. It should work as follows:
#include <stdio.h>
#include <iostream>
int main() {
_fmode = _O_BINARY;
std::ofstream f("a.txt"); // opens in binary mode
}
EDIT: As of 2021, Windows 10 Notepad understands UNIX line endings.