It's been an unpleasant surprise that '\n'
is replaced with "\r\n"
on Windows, I did not know that. (I am guessing it is also replaced on Mac...)
Is there an easy way to ensure that Linux, Mac and Windows users can easily exchange text files?
By easy way I mean: without writing the file in binary mode or testing and replacing the end-of-line chars myself (or with some third party program/code). This issue effects my C++ program doing the text file I/O.
If you really just want an ASCII LF, the easiest way is to open the file in binary mode: in non-binary mode \n is replaced by a platform specific end of line sequence (e.g. it may be replaced by a LF/CR or a CR/LF sequence; on UNIXes it typically is just LF). In binary mode this is not done. Turning off the replacement is also the only effect of the binary mode.
BTW, using endl is equivalent to writing a \n followed by flushing the stream. The typically unintended flush can become a major performance problem. Thus, endl should be use rarely and only when the flush is intended.
The issue isn’t with
endl
at all, it’s that text streams reformat line breaks depending on the system’s standard.If you don’t want that, simply don’t use text streams – use binary streams. That is, open your files with the
ios::binary
flag.That said, if the only issue is that users can exchange files, I wouldn’t bother with the output mode at all, I’d rather make sure that your program can read different formats without choking. That is, it should accept different line endings.
This is by the way what any decent text editor does (but then again, the default
notepad.exe
on Windows is not a decent text editor, and won’t correctly handle Unix line breaks).Sorry for 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 callflush
. So in fact you almost never want to use it.Misconception: 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. In fact it's what you want to do, since it has better-defined semantics and results in more portable code. 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:
Alternatively use any of the ways described here.