Changing std::endl to put out CR+LF instead of LF

2019-03-25 13:55发布

I'm writing a program on a Linux platform that is generating text files that will be viewed on, inevitably, a Windows platform.

Right now, passing std::endl into a ostream generates the CR character only for newlines. Naturally, these text files look wrong in MS Notepad.

  1. Is there a way to change std::endl such that it uses CR+LF for newline instead of LF?
  2. I know I could write my own custom manipulator, like win_endl, for generating my own newlines, but I use the std::endl symbol in a lot of places, and like many programmers, have a tendency to do the thing that requires the least work possible. Could I simply overload std::endl to produce CR+LF, or is this a dumb idea for maintainability?

NB: I checked out this question, but it's asking about going the other way, and the accepted answer seems rather incomplete.

5条回答
三岁会撩人
2楼-- · 2019-03-25 14:08

Windows Notepad is pretty much the only Windows program you'll find that doesn't handle LF-only files properly. Almost everything else (including WordPad) handles LF-only files just fine.

This problem is a bug in Notepad.

查看更多
ら.Afraid
3楼-- · 2019-03-25 14:16

You shouldn't use \r\n. Just use \n, but then open the stream in "text" mode, which than will do the conversion for you. You may not care about cross-platform, but this is the official way of doing it.

That way, the same code will spit-out \n on unix, \r\n on windows, and \r on mac.

查看更多
对你真心纯属浪费
4楼-- · 2019-03-25 14:16

Here was my solution to the problem. It's a bit of a mash-up of all the info provided in the answers:

  1. I created a macro in a win_endl.h file for the newline I wanted:

    #define win_endl "\r\n"
    
  2. Then I did a search-and-replace:

    sheepsimulator@sheep\_machine > sed -i 's/std::endl/win_endl' *
    

And ensured all my files included win_endl.h.

查看更多
贼婆χ
5楼-- · 2019-03-25 14:17

Opening a file in text mode should cause std::endl to be converted to the appropriate line ending for your platform. Your problem is that newline is appropriate for your platform, but the files you create aren't intended for your platform.

I'm not sure how you plan on overloading or changing endl, and changing its behavior would certainly be surprising for any developers new to your project. I'd recommend switching to win_endl (should be a simple search-and-replace) or maybe switching from a standard ostream to a Boost.Iostreams filtering stream to do the conversion for you.

查看更多
劳资没心,怎么记你
6楼-- · 2019-03-25 14:22

std::endl is basicly:

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

So just use "\r\n" instead and omit the flush. It's faster that way, too!

From the ostream header file on endl:

This manipulator is often mistakenly used when a simple newline is desired, leading to poor buffering performance.

查看更多
登录 后发表回答