Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Escape sequence for a true LineFeed (LF)

Tags:

c

In C we have a couple common escape sequences:

\r for a Carriage Return (CR) - which would be the equivalent of doing '\015'

\n is often described as LineFeed, but I understand that '\n' will get translated in a string as required to CRLF (dependant on the OS) - which would be the equivalent of doing "\015\012". In particular if I'm dong a printf or an fprintf.

Is there an escape code for a true line feed character that won't get translated or am I stuck using '\012' when I don't want it translated?

like image 717
BIBD Avatar asked Aug 31 '16 17:08

BIBD


Video Answer


3 Answers

There is no translation in the C compiler. A string of [and these are all equivalent]:

// (1) these are all equivalent to a string of newline of length 1:
"\n"
"\x0a"
"\012"

// (2) these are all equivalent to a string of carriage return of length 1:
"\r"
"\x0d"
"\015"

// (3) these are all equivalent to a string of CRLF of length 2:
"\r\n"
"\x0d\0x0a"
"\015\012"

When outputting to a terminal under a POSIX system, the TTY driver will convert case (1) into CRLF in cooked mode. This can be changed via some TTY ioctl calls. IIRC, similar for windows(?). But, [again] IIRC, windows has some windows specific call that must be done because the translation is done at a very low layer.

When writing to a file under a POSIX system, no translation is done.

However, when writing to a file under Windows, case (1) is translated by the OS to CRLF for normal opens [because the default is "text" mode]:

open(file,O_WRONLY);
fopen(file,"w");

To suppress the translation under windows for case (1), open the file in "binary" mode:

open(file,O_WRONLY | O_BINARY);
fopen(file,"wb");

Binary mode is also applicable for opening in read mode. And, for POSIX, it is [effectively] a no-op and is ignored. With/without the binary option, under POSIX, is opening in binary mode because POSIX has no "text mode" for files.

So, for portability between POSIX/windows, this is the mode to use to suppress translation.

like image 132
Craig Estey Avatar answered Oct 23 '22 15:10

Craig Estey


@Barmar is right: \n and \012 are the exact same bits. The difference between a plain LF and a CRLF on Windows machines is how you open whatever device you are writing to. If you are doing printf to a terminal under cygwin, you could stty to change to raw mode, for example. Otherwise, it will depend on the specifics of the C library you are using.

Edit For Win32 using msvcrt, using fopen(..., "b"), "translations involving carriage-return and linefeed characters are suppressed" (from MSDN). By contrast, in text mode, "linefeed characters are translated to carriage return–linefeed combinations on output" (same source).

So to answer the original question, there is no single escape sequence that will always be \012 on output, on every platform, with every output routine.

like image 40
cxw Avatar answered Oct 23 '22 14:10

cxw


The history:

Old mainframe computers had terminals connected over often slow connections. The terminals were typewriters. After the user had typed a line, they pressed return (as on old typewriters). This was the signal for the mainframe to process the line. Once the mainframe had received and processed the line, it sent a line feed. The paper of the typewriter now went up one line, informing the user the system was ready to receive another line.

Unix, being based on timesharing, copied this behavior.

(But I am still not sure whether the LF is stored under Unix, or the CR - from the above, it should be the CR and the system adds the LF.)

Windows, not being timesharing, just put the CR and LF into the file.

like image 24
Paul Ogilvie Avatar answered Oct 23 '22 14:10

Paul Ogilvie