2

When I am trying to operate a text file I hope to set the end-of-line character as what is preferred on the destination OS, say, LF in linux text files and CRLF in windows text files.

Related questions

According to question C++: Is there a standard definition for end-of-line in a multi-line string constant? the eol character depends on the characters in source files. That means, when i use

std::ofstream out{"hello.txt"};
out << R"(Hello
World)" << std::endl;

the eol characters in "hello.txt" maps to a single '\n' character, even when the source file is stored in windows text format.

According to questions Detect Windows or Linux in C, C++ and Standard #ifdef for Cygwin, I may use

#if defined(_WIN32) || defined(__CYGWIN__)
#define END_OF_LINE "\n\r"
#else
#define END_OF_LINE "\n"

However, i have no idea how to put these codes into the former code segment.

Java solution

In java, use

System.getProperty("line.separator");

will return the corresponding end-of-line characters.

JDK 7 replaces the above line with System.lineSeparator(), which is more efficient.

C++ solution?

C++17 filesystem provides a constant: std::filesystem::path::preferred_separator to tell the path separator on various OS platforms. I think this is a good form.

Is there any existing facilities in C++17 or newer standards providing such convenience as std::xxx::preferred_eol_separator?

Community
  • 1
  • 1
AlohaWorld
  • 51
  • 1
  • 6

1 Answers1

1

Yes and funny enough -- it's called '\n'. The reason is, the interpretation of NEW LINE character in output I/O operations from standard library (printf()s, couts and their families) depends on how you open a file for writing. E.g.

fopen("path", "w");

marks the file as "writable file" on POSIX and "writable text file" on Windows. POSIX will do no translation of the contents of the input buffer, while on Windows every '\n' will be stored as CRLF pair. On the other hand,

fopen("path", "wb");

marks the file as "writable file" on POSIX (again) and "writable binary file" on Windows. This time, neither POSIX nor Windows will do any translation.

The same thing happens with input files: "r" will be treated as "readable text file", "rb" will be treated as "readable binary file", and on Windows any read operation on a "text" file will report any CRLF as a lone \n back into the application.

This approach is also available in iostreams, where all of cout, cerr and clog are treated as text files, while ofstream and ifstream can have a std::ios_base::binary flag in constructor to distinguish between text and binary mode.

Marcin Zdun
  • 142
  • 1
  • 8