Как да накарам cout да се държи като в двоичен режим?

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

Има ли начин на земята да го спре да прави това и просто да изведе "\n" на всеки 'cout ‹‹ "\n"'?

Благодаря предварително.


person lithuak    schedule 13.04.2011    source източник
comment
защо да го правиш Windows предпочита CRLF пред LF. Няколко зле написани приложения (включително поне по-стари версии на текстовия редактор по подразбиране) ще имат проблеми с него. Освен ако всъщност не се занимавате с двоични данни (въпросът не го посочва изрично), не трябва да ви пука.   -  person    schedule 13.04.2011
comment
denlan: според изискванията моят код трябва да работи под Windows И да произвежда изход, дефиниран в спецификацията, която за съжаление казва, че разделителите на редовете са строго \n. \r\n нарушава други помощни програми, които също следват спецификацията и очакват САМО \n-разделени файлове при въвеждане :( Това е повече или по-малко стандартна бъркотия с поддържащ наследен код/система.   -  person lithuak    schedule 13.04.2011


Отговори (2)


Това работи с помощта на 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].

person Rob K    schedule 19.12.2014

Не вярвам, че можете да принудите std::cout да извежда двоични данни. Интерфейсът от най-ниско ниво, достъпен за потребителя чрез C++, е streambuf в std::cout.rdbuf(). Можете доста добре да предположите, че обектът е от тип basic_filebuf и раздел §27.9.1.4 от стандарта C++11 изисква basic_filebuf да прилага отделни текстови и двоични режими.

Проверете вашите специфични за платформата разширения за начин да отворите друг поток към stdout, като използвате неговия файлов дескриптор. След това можете да посочите std::binary в флаговете на режима.

Вероятно обаче е по-лесно да прехвърлите изхода през втора програма, която преобразува краищата на редовете.

Редактиране: Сега виждам, че може да сте склонни да отидете малко по-далеч, за да накарате програмата наистина да извежда директно това, което искате.

Можете да използвате C интерфейса за извеждане на нови редове, стига 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
    }
}
person Potatoswatter    schedule 13.04.2011