Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find the system's line terminator

Is there a header file somewhere that stores the line termination character/s for the system (so that without any #ifdefs it will work on all platforms, MAC, Windows, Linux, etc)?

like image 486
soandos Avatar asked Jan 29 '13 15:01

soandos


4 Answers

You should open the file in "text mode" (that is "not use binary"), and newline is always '\n', whatever the native file is. The C library will translate whatever native character(s) indicate newlines into '\n' whenever appropriate [that is, reading/writing text files]. Note that this also means you can't rely on "counting the number of characters read and using that to "seek back to this location".

If the file is binary, then newlines aren't newlines anyways.

And unless you plan on running on really ancient systems, and you REALLY want to do this, I would do:

#ifdef __WINDOWS__    // Or something like that
#define END_LINE    "\r\n"
#else
#define END_LINE    "\n"
#endif

This won't work for MacOS before MacOS X, but surely nobody is using pre-MacOS X hardware any longer?

like image 151
Mats Petersson Avatar answered Nov 11 '22 19:11

Mats Petersson


No, because it's \n everywhere. That expands to the correct newline character(s) when you write it to a text file.

like image 35
MSalters Avatar answered Nov 11 '22 20:11

MSalters


Posix requires it to be \n. So if _POSIX_VERSION is defined, it's \n. Otherwise, special-case the only non-POSIX OS, windows, and you're done.

like image 1
R.. GitHub STOP HELPING ICE Avatar answered Nov 11 '22 19:11

R.. GitHub STOP HELPING ICE


It doesn't look like there's anything in the standard library to obtain the current platform's line terminator.

The closest looking API is

char_type  std::basic_ios::widen(char c);

It "converts a character c to its equivalent in the current locale" (cppreference). I was pointed at it by the documentation for std::endl which "inserts a endline character into the output sequence os and flushes it as if by calling os.put(os.widen('\n')) followed by os.flush()" (cppreference).

On Posix,

  • widen('\n') returns '\n' (as a char, for char-based streams);
  • endl inserts a '\n' and flushes the buffer.

On Windows, they do exactly the same. In fact

#include <iostream>
#include <fstream>
using namespace std;
int main() {
    ofstream f;
    f.open("aaa.txt", ios_base::out | ios_base::binary);
    f << "aaa" << endl << "bbb";
    f.close();
    return 0;
}

will result in a file with just '\n' as a line terminator.

As others have suggested, when the file is open in text mode (the default) the '\n' will be automatically converted to '\r' '\n' on Windows.

(I've rewritten this answer because I had incorrectly assumed that std::endl translated to "\r\n" on Windows)

like image 1
6 revs Avatar answered Nov 11 '22 20:11

6 revs