How to make cout behave as in binary mode?
Asked Answered
S

2

18

Every time I do 'cout << endl' or even 'cout << "\n"' and then launch my program under Windows to output to a file ("a.exe < test.in > result.out") I get "\r\n" line endings in "result.out".

Is there on earth a way to stop it doing so and just output "\n" on every 'cout << "\n"'?

Thanks in advance.

Seabury answered 13/4, 2011 at 18:52 Comment(2)
Why do it? Windows prefers CRLF over LF. Several poorly-written applications (including at least older versions of the default text editor) will have trouble with it. Unless you're actually dealing with binary data (the question doesn't explicitly state it), you shouldn't have to care.Psychopathology
denlan: by requirments my code should run under Windows AND produce output defined in specification which unfortunately says that line delimeters are strictly "\n". The "\r\n" breaks other utils which also follow specification and expect ONLY "\n"-delimited files on input :( Its a more or less standard mess with supporting legacy code/system.Seabury
C
10

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].

Compensation answered 19/12, 2014 at 18:56 Comment(0)
C
5

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
    }
}
Censorious answered 13/4, 2011 at 19:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.