13

Thinking about UNIX, Windows and Mac and an output stream (both binary and text),

What does std::endl represent, i.e. <CR><LF>, <LF> or <CR>? Or is it always the same no matter what platform/compiler?

The reason I'm asking is that I'm writing a TCP client that talks a protocol that expects each command to end in <CR><LF>. So I'm wondering whether to use std::endl or "\r\n" in my streams.

EDIT: Ok, so one flushes the buffer and another doesn't. I get that. But if I'm outputting text to a file, is '\n' equal to <LF> or does it convert to <CR><LF> on Windows and <LF> on Unix or not? I don't see a clear answer yet.

hochl
  • 12,524
  • 10
  • 53
  • 87
hookenz
  • 36,432
  • 45
  • 177
  • 286

5 Answers5

12

The code:

stream << std::endl;

// Is equivalent to:

stream << "\n" << std::flush;

So the question is what is "\n" mapped too.
On normal streams nothing happens. But for file streams (in text mode) then the "\n" gets mapped to the platfrom end of line sequence. Note: The read converts the platform end of line sequence back to a '\n' when it reads from a file in text mode.

So if you are using a normal stream nothing happens. If you are using a file stream, just make sure it is opened in binary mode so that no conversion is applied:

stream << "\r\n"; // <CR><LF>
Martin York
  • 257,169
  • 86
  • 333
  • 562
7

The C++ standard says that it:

Calls os.put(os.widen(’\n’) ), then os.flush()

What the '\n' is converted to, if it is converted at all, is down to the stream type it is used on, plus any possible mode the stream may be opened in.

4

Use stream << "\r\n" (and open the stream in binary mode). stream << std::endl; is equivalent to stream << "\n" << flush;. The "\n" might be converted to a "\r\n" if the code runs on Windows, but you can't count on it -- at least one Windows compiler converts it to "\n\r". On a Mac, it's likely to be converted to "\r" and on Unix/Linux and most similar systems, it'll be left as just a "\n".

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • If `\n` is converted to `\r\n`, then wouldn't `\r\n` be translated to `\r\r\n`? Merely using `\r\n` wouldn't be enough, then. He'd also have to make sure the stream was in binary mode to suppress the translation. – Rob Kennedy Dec 15 '09 at 23:35
  • `\n` is converted to whatever is appropriate on a given platform, if the stream is opened in text mode (i.e. if you didn't use `ios_base::binary` flag), and you _can_ count on it. – Pavel Minaev Dec 15 '09 at 23:45
  • Of course, if one needs `\r\n` in the stream regardless of the platform, then `"\r\n"` must be used, and furthermore, the stream must be opened with `ios_base::binary`. – Pavel Minaev Dec 15 '09 at 23:45
  • @Pavel:According to the standard, text mode simply gives an implementation defined mapping. Yes, it'll usually be what you expect, but it's a QoI issue. I know of a compiler for Windows that converts "\n" to "\n\r" instead of "\r\n". As long as it's properly documented, the implementation could include a provision like "...except on the second Tuesday of the month..." – Jerry Coffin Dec 15 '09 at 23:51
  • @JerryCoffin Documented or not, I would consider that a significant bug. On Windows, `\r\n` is the canonical newline; Notepad doesn't recognize `\n\r` as a newline, and other Windows text editors that do process non-Windows newlines, such as WordPad and Notepad++, will parse `\n\r` as a Unix newline followed by a Mac newline and give you two line breaks. What compiler is this, and why would they do that in the first place if it was a purposeful choice? – JAB Jun 28 '13 at 17:36
  • @JAB: offhand, I can't remember which. I'm pretty sure I never used it, but had to deal with some data files that came from it. As to how `\n\r` will be interpreted, that depends -- for example, Microsoft's library (of the time) handled it without any problems, but Borland's didn't. I can't even guess why they did it. – Jerry Coffin Jun 28 '13 at 18:17
2

Quoted from the accepted answer on a related question:

The varying line-ending characters don't matter, assuming the file is open in text mode, which is what you get unless you ask for binary. The compiled program will write out the correct thing for the system compiled for.

The only difference is that std::endl flushes the output buffer, and '\n' doesn't. If you don't want the buffer flushed frequently, use '\n'. If you do (for example, if you want to get all the output, and the program is unstable), use std::endl

In your case, since you specifically want <CR><LF>, you should explicitly use \r\n, and then call std::flush() if you still want to flush the output buffer.

Community
  • 1
  • 1
e.James
  • 116,942
  • 41
  • 177
  • 214
  • Rep. for quoting the accepted answer to a dupe question? Where are the fifteen or so SO nazis when you need them – Rob Wells Dec 15 '09 at 22:59
  • @Rob Wells: I thought about that, but decided that it isn't any different from quoting another reference source in my answer, which is, of course, perfectly acceptable. The upvotes are for providing information relevant to the question at hand. – e.James Dec 15 '09 at 23:20
  • 1
    Rob, I see no duplicates. This question and the cited one are certainly similar, but they're not exact duplicates. Furthermore, James adds a summary after the quotation to specifically address this question. Besides, people get reputation for quoting answers they find elsewhere all the time. Should it make a difference if "elsewhere" is the same Web site? Are you jealous, or what? – Rob Kennedy Dec 15 '09 at 23:38
  • @Rob and @eJames, nah, not jealous, just in a bad mood after trying to unclog a horrible set of Apache configs left by someone who's emigrated to Australia and is uncontactable! But at least it's only for the BBC's iPlayer DL platform so it doesn't really matter. NOT! >:-< But I'm smiling now! (-: – Rob Wells Dec 16 '09 at 12:43
0

Looks like your question got munged. Each command ends in []? For an over-the-wire protocol, I'd suggest using a delimiter that doesn't vary by platform. std::endl could resolve to '\r\n' or '\n\r' depending on the platform.

Jim Lamb
  • 25,355
  • 6
  • 42
  • 48