C++ переводит новую строку с CR+LF на LF
Я пишу код, который работает в Windows и выводит текстовый файл, который впоследствии становится входом для программы в Linux. Эта программа ведет себя некорректно, когда передаются файлы с символами новой строки, которые являются CR+LF, а не просто LF.
Я знаю, что могу использовать такие инструменты, как dos2unix, но я бы хотел пропустить дополнительный шаг. Можно ли заставить программу на C++ в Windows использовать новую строку для Linux вместо Windows?
3 ответа
Да, вы должны открыть файл в "двоичном" режиме, чтобы остановить перевод новой строки.
Как вы это сделаете, зависит от того, как вы открываете файл.
С помощью fopen
:
FILE* outfile = fopen( "filename", "wb" );
С помощью ofstream
:
std::ofstream outfile( "filename", std::ios_base::binary | std::ios_base::out );
Хорошо, так что это, вероятно, не то, что вы хотите услышать, но вот мои $0,02 на основе моего опыта с этим:
Если вам нужно передавать данные между различными платформами, в конечном итоге вам, вероятно, лучше использовать формат, который не заботится о том, как выглядят разрывы строк. Если это текстовые файлы, пользователи иногда будут связываться с ними. Если путаница в конце строки приведет к сбою приложения, это будет приложение с интенсивной поддержкой.
Был там, сделал это, перешел на XML. Сделали поддержку ребята намного счастливее.
Гораздо более понятным решением является использование escape-последовательности ASCII для символа LF (десятичное число 10): '\012' или '\x0A' представляет явный однострочный перевод независимо от платформы.
Этот метод также позволяет избежать сюрпризов, связанных с длиной строки, поскольку '\n' может расширяться до двух символов. Но то же самое может быть и с многобайтовыми символами Юникода в UTF8, когда они записываются непосредственно в строковый литерал в исходном коде.
Также обратите внимание, что '\r' - это независимый от платформы код для одиночного возврата каретки (десятичное 13). Символ '\f' - это не перевод строки, а скорее перевод формы (десятичное 12), который не является переводом строки ни на одной из известных мне платформ. C не предлагает односимвольный экранирование обратной косой черты для перевода строки, поэтому необходимы более длинные восьмеричные или шестнадцатеричные escape-символы.