Переносной конец строки (новая строка) - PullRequest
11 голосов
/ 31 декабря 2011

Было неприятным сюрпризом, что '\n' заменяется на "\r\n" в Windows, я этого не знал. (Я предполагаю, что это также заменено на Mac ...)

Существует ли простой способ обеспечить пользователям Linux, Mac и Windows возможность легко обмениваться текстовыми файлами?

Под простым способом я подразумеваю: не писать файл в двоичном режиме, не тестировать и не заменять символы конца строки самостоятельно (или какой-либо сторонней программой / кодом). Эта проблема влияет на мою программу C ++, выполняющую ввод / вывод текстового файла.

Ответы [ 3 ]

12 голосов
/ 31 декабря 2011

Проблема вовсе не в endl, а в том, что текстовые потоки переформатируют разрывы строк в зависимости от стандарта системы.

Если вы этого не хотите, просто не используйте текстовые потоки - используйте двоичные потоки. То есть откройте ваши файлы с флагом ios::binary.

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

Это, кстати, то, что делает любой приличный текстовый редактор (но опять же, по умолчанию notepad.exe в Windows , а не приличный текстовый редактор, и он не будет правильно обрабатывать разрывы строк Unix).

11 голосов
/ 31 декабря 2011

Извините за частичное совпадение с другими ответами, но ради полноты:

Миф: endl является «более переносимым», так как записывает окончание строки в зависимости от платформысоглашение.

Правда: endl определено для записи '\ n' в поток, а затем вызова flush.Так что на самом деле вы почти никогда не хотите его использовать.

Заблуждение: Вы должны открывать файлы в текстовом режиме для записи текста и в двоичном режиме для записи двоичных данных.

Правда: Текстовый режим существует в первую очередь потому, что некоторое время назад существовали файловые системы, которые различали текстовые файлы и двоичные файлы.Это больше не верно для любой здравомыслящей платформы, которую я знаю.Вы также можете писать текст в бинарные файлы.Фактически это то, что вы хотите сделать, так как он имеет более определенную семантику и приводит к более переносимому коду.Обратите внимание, что POSIX не не различает двоичный и текстовый режим.

Как сделать текст: Откройте все в двоичном режиме и используйте обычный старый \ n,Вам также нужно будет позаботиться о кодировке.Стандартизировать UTF-8 для Unicode-корректности. Используйте для внутреннего использования узкие строки в кодировке UTF-8 вместо wchar_t, который отличается на разных платформах.Ваш код станет проще для переноса.

Совет: Вы можете заставить MSVC по умолчанию открывать все файлы в двоичном режиме.Он должен работать следующим образом:

#include <stdio.h>
#include <iostream>
int main() {
    _fmode = _O_BINARY;
    std::ofstream f("a.txt"); // opens in binary mode
}

В качестве альтернативы используйте любой из способов , описанных здесь .

6 голосов
/ 31 декабря 2011

Если вы действительно хотите использовать ASCII LF, самый простой способ - открыть файл в двоичном режиме: в недвоичном режиме \ n заменяется на конец последовательности строк для конкретной платформы (например, он может быть заменен на LF)./ CR или последовательность CR / LF; в UNIX это обычно просто LF).В двоичном режиме это не делается.Отключение замены также является единственным эффектом двоичного режима.

Кстати, использование endl эквивалентно записи \ n с последующей очисткой потока.Обычно непреднамеренная очистка может стать серьезной проблемой производительности.Таким образом, endl следует использовать редко и только тогда, когда предназначен сброс.

...