Portable end of line
Asked Answered
K

5

21

is there any way to automatically use correct EOL character depending on the OS used?

I was thinking of something like std::eol?

I know that it is very easy to use preprocessor directives but curious if that is already available.

What I am interested in is that I usually have some messages in my applications that I combine later into a single string and I want to have them separated with a EOL. I know that I could use std::stringstream << endl but it seems to be an overkill sometimes instead of a regular append.

Kajdan answered 26/3, 2010 at 2:51 Comment(0)
O
19

std::endl is defined to do nothing besides write '\n' to the stream and flush it (§27.6.2.7). Flushing is defined to do nothing for a stringstream, so you're left with a pretty way of saying mystringstream << '\n'. The standard library implementation on your OS converts \n appropriately, so that's not your concern.

Thus endl is already the ultimate in performance and portability, and the only other thing you could want is << '\n' if you are trying to efficiently write to a file (not a stringstream). Well, << '\n' does also eliminate the pointless virtual call to stringbuf::flush. Unless profiling shows that empty function call to be taking time, don't think about it.

Obsolescent answered 26/3, 2010 at 7:39 Comment(5)
I figured that using '\n's everywhere is totally fine and OS (read Windows) automatically handles it to become \r\n when I write to console and to files. It is more than enough for me at this point.Kajdan
@Potatoswatter: maybe what you were pointing to (assuming it's the C++ standard) is now section §27.7.3.8?Norty
@Norty Yes, that's a reference to C++03 which was current at the time. The numbers change, but the section is named [lib.ostream.manip]. Anyway, there's nothing really to see there. It just says "Effects: Calls os.put(os.widen(’\n’) ), then os.flush()."Obsolescent
I'd like to point out that flush isn't pointless. If you're debugging using cout statements, you better be using endl, or you're not guaranteed to have the statement print out when you expect it to be printed out. Same goes for multithreaded console output (although that case is a mess even with endl)Gyp
@Gyp This answer is meant to be read in context. This stream isn't cout. Multithreading requires a mutex lock, flushing might seem to help reduce the symptoms of a race condition but it's a non-solution.Obsolescent
S
11

If you want to write a line separator to a stream:

std::cout << '\n';

or

std::cout << "\n";

or

std::cout << "whatever you were going to say anyway\n";

If the stream is text mode and the OS uses anything other than LF as a separator, it will be converted.

If you want to write a line separator and flush the stream:

std::cout << std::endl;

If you have binary-mode output for whatever reason, and you want to write a platform-specific line break, then I think you might have to do it indirectly (write '\n' to a text stream and then examine it in binary mode to see what you get). Possibly there's some way to directly get the line break sequence from the implementation, that I'm not aware of. It's not a great idea, anyway: if you're writing or reading a file in binary mode then it should be in a format which defines line breaks independently of the OS, or which doesn't have lines at all. That's what binary mode is for.

Samsun answered 26/3, 2010 at 2:58 Comment(0)
M
2

Just open a file in text mode

FILE *fp = fopen( "your_file.txt", "w+t" );

and then

fprintf( fp, "some string and integer %d\n", i );
fclose(fp);

and the OS will take care of the EOL accordingly to its standards.

Myogenic answered 26/3, 2010 at 2:55 Comment(6)
Eheh i'm an old school one XDMyogenic
Now you've forgotten to close the file. :PIrascible
Please don't fopen() in production code, for reasons of exception safety. Use STL RAII equivalents.Thorfinn
C'mon it was just an example, do you expect to have a file named "your_file.txt" in a production environment too?Myogenic
@Simone: It's easy to see that the file name needs to adapted from your example. It's nigh impossible to see that one shouldn't use the C std lib for dealing with files.Angleaangler
I'm not seeing how the OS will take care of the EOL. In that example the EOL character will be \n, which the OS should not change.Harter
N
1

Well, the STL has std::endl, which you can use as

std::cout << "Hi five!" << std::endl;

Note that besides adding an endline, std::endl also flushes the buffer, which may have undesirable performance consequences.

Nicholas answered 26/3, 2010 at 2:59 Comment(3)
Err... that's not STL, that's iostreams.Bainmarie
I agree with BillyONeal. Also, when you just want an '\n', just write '\n', not std::endl. I've once seen a speedup by a factor of 8 after replacing needless std::endl by '\n'.Angleaangler
Oh, I didn't know those are separate entities. I'd just assumed that they because they share the namespace. Thanks for the correction.Nicholas
T
1

Files, even text files, are often transferred between machines, so "os-specific new line character" is an oxymoron.

It is though true that operating systems have a say on that matter, particularly one operating systems aka Windows, although many windows programs will read \n-spaced files correctly, even though the winapi multiline edit control would not. I suggest you consider twice what is the right for you: it's not necessarily what your OS recommends. If your files are ever to be stored on removable media, do not use OS standard. Use global standard, 0xA.

Thorfinn answered 26/3, 2010 at 3:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.