How to make cout behave as in binary mode?

Solution 1:

This works using Visual Studio 2013:

#include <io.h>
#include <fcntl.h>
#include <iostream>

int main( int argc, char * argv[] )
{
    _setmode( _fileno( stdout ),  _O_BINARY );
    std::cout << std::endl;
}

It will output only [0A], and not [0D][0A].

Solution 2:

I don't believe you can force std::cout to output binary data. The lowest-level interface available to the user through C++ is the streambuf at std::cout.rdbuf(). You can pretty well assume that object is of type basic_filebuf, and section §27.9.1.4 of the C++11 standard requires that basic_filebuf implement separate text and binary modes.

Check your platform-specific extensions for a way to open another stream to stdout using its file descriptor. Then you can specify std::binary in the mode flags.

However, it's probably easier to pipe the output through a second program that converts the line endings.

Edit: Now I see that you might be willing to go a little further to truly make the program directly output what you want.

You can use the C interface to output newlines as long as the C++ interface is set to unbuffered mode.

At the very beginning of your program, before cout receives any output, do this:

std::cout.rdbuf()->pubsetbuf( 0, 0 ); // go to unbuffered mode

When you want to output a newline, do it like so:

_write( STDOUT_FILENO, 1, "\n" ); // do not convert line ending

You can wrap this little… nugget… inside a custom manipulator:

#include <unistd.h>

std::ostream &endln( std::ostream &s ) {
    if ( s->rdbuf() == std::cout.rdbuf() ) { // this is cout or cerr into cout
        _write( STDOUT_FILENO, 1, "\n" ); // do not convert line ending
        return s; // stream is unbuffered, no need to flush
    } else {
        return std::endl( s ); // other streams do convert to \r\n
    }
}