Как заставить cout вести себя как в двоичном режиме?

Каждый раз, когда я делаю 'cout < < endl 'или даже' cout < "\n" ', а затем запустите мою программу под Windows для вывода в файл ( "a.exe < test.in > result.out" ). Я получаю окончание строк "\ r\n" в "result.out".

Есть ли на Земле способ остановить это и просто вывести "\n" на каждом "cout <" \ П"?

Спасибо заранее.

Ответы

Ответ 1

Это работает с использованием 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;
}

Он выводит только [0A], а не [0D] [0A].

Ответ 2

Я не верю, что вы можете заставить std::cout выводить двоичные данные. Интерфейс самого низкого уровня, доступный пользователю через С++, - это streambuf at std::cout.rdbuf(). Вы вполне можете предположить, что объект имеет тип basic_filebuf, а в разделе § 27.9.1.4 стандарта С++ 11 требуется, чтобы basic_filebuf реализовал отдельный текстовый и двоичный режимы.

Проверьте свои расширения для платформы, чтобы открыть другой поток для stdout, используя его файловый дескриптор. Затем вы можете указать std::binary в флагах режима.

Однако, возможно, проще передать вывод через вторую программу, которая преобразует окончание строки.

Изменить: Теперь я вижу, что вы можете пойти немного дальше, чтобы действительно заставить программу напрямую выводить то, что вы хотите.

Вы можете использовать интерфейс C для вывода новых строк, если интерфейс С++ установлен в небуферизованный режим.

В самом начале вашей программы, прежде чем cout получит какой-либо вывод, сделайте следующее:

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

Если вы хотите вывести новую строку, сделайте это так:

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

Вы можете обернуть этот маленький... самородок... внутри настраиваемого манипулятора:

#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
    }
}