Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Portable end of line (newline)

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.

like image 844
Ali Avatar asked Dec 31 '11 16:12

Ali


People also ask

Does Mac use LF or Crlf?

The default value on both Windows and Mac Classic clients is crlf .

What is CR LF characters?

CR = Carriage Return ( \r , 0x0D in hexadecimal, 13 in decimal) — moves the cursor to the beginning of the line without advancing to the next line. LF = Line Feed ( \n , 0x0A in hexadecimal, 10 in decimal) — moves the cursor down to the next line without returning to the beginning of the line.

What are newline characters?

The newline character ( \n ) is called an escape sequence, and it forces the cursor to change its position to the beginning of the next line on the screen. This results in a new line.

What is\ n line break?

For example, in Linux a new line is denoted by “\n”, also called a Line Feed. In Windows, a new line is denoted using “\r\n”, sometimes called a Carriage Return and Line Feed, or CRLF. Adding a new line in Java is as simple as including “\n” , “\r”, or “\r\n” at the end of our string.


2 Answers

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.

like image 161
Yakov Galka Avatar answered Sep 22 '22 02:09

Yakov Galka


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).

like image 43
Konrad Rudolph Avatar answered Sep 26 '22 02:09

Konrad Rudolph