Как обнаружить разрыв строки в C ++?

в окнах разрыв строки

\r\n

в Linux,

\n

Я не хочу менять свой код, когда он работает в другой ОС, я просто хочу перекомпилировать его напрямую.

Итак, как обнаружить это в C ++? Определена ли в стандартной библиотеке константа или функция для ее обнаружения?


person Tio Plato    schedule 09.04.2015    source источник
comment
В зависимости от того, что вы делаете, я полагаю, что поиск std::endl будет работать   -  person VoidStar    schedule 09.04.2015
comment
Просто прочтите строку из файла @VoidStar   -  person Tio Plato    schedule 09.04.2015


Ответы (3)


Детали, зависящие от платформы, которые необходимо инкапсулировать в абстракции. Так что просто предоставьте простой класс TextInfo (?) И добавьте туда статическую функцию или, возможно, открытый статический член, который вернет окончание строки.

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

#ifdef WINDOWS
return "\r\n";
#endif
#ifdef LINUX
return "\n";
#endif

Теперь вам просто нужно предоставить разные целевые компиляции (возможно, они у вас уже есть). Для целей вам нужно добавить еще одно определение для команды компиляции (-D для gcc и / D для VS).

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

person senfen    schedule 09.04.2015
comment
Ты неправ. #ifdef LINUX вообще не работает, вам следует заменить его на #ifdef unix, и #ifdef WINDOWS также неверен, замените его на #ifdef WIN32 - person Tio Plato; 09.04.2015
comment
Пожалуйста, прочтите ответ полностью. Также с этой частью: For targets you need to add one more define to compile command. Я не использую «стандартные» определения, потому что они зависят от компилятора. Предоставьте свои собственные, добавив их в команду компиляции. - person senfen; 09.04.2015
comment
Я понял твою идею. Но, пожалуйста, используйте стандарт. - person Tio Plato; 09.04.2015
comment
И я хочу знать, определяла ли стандартная библиотека подобный класс? - person Tio Plato; 09.04.2015
comment
Но таких стандартных определений нет! И поэтому я заключил это в кавычки. В другом компиляторе вам нужно будет использовать другой макрос, чтобы проверить, что лучше всего предоставить собственный. Оба макроса, которые вы показали, являются макросами для конкретного компилятора. Вам нравится универсальность перевода строки с помощью макросов, специфичных для компилятора? - person senfen; 09.04.2015
comment
Для этого нет стандартного класса, и нет стандартного класса для разницы в '\' и '/' в каталогах unix и Windows :) - person senfen; 09.04.2015

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

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

Единственная проблема, с которой вы столкнетесь, - это перенос файла данных в стиле Windows в UNIX или наоборот. Если это именно то, что вы делаете, вы можете просто изменить строку, которую вы читаете, так, чтобы любой символ \r в конце был удален.

Обратите внимание, что не отрицательно влияет на файлы в стиле Windows, поскольку в памяти они не имеют символа \r - он помещается в файл только при записи.

person paxdiablo    schedule 09.04.2015
comment
Гм, это зависит от того, читаете ли вы контент в двоичном или текстовом режиме, кроме того, сетевые протоколы, такие как http / smtp, используют \ r \ n для указания новой строки. Если он использует только текстовый режим, вы совершенно правы, если он смешивает двоичный / текстовый режим, ему следует быть очень осторожным с этим аспектом, и, как я уже сказал, если он работает с сетевыми протоколами, он должен их учитывать. - person Jose Palma; 09.04.2015
comment
Я не думаю, что вам нужно беспокоиться о чтении файлов UNIX в Windows - библиотека C обычно игнорирует отсутствующий \r. - person MSalters; 09.04.2015

Если вы не перемещаете файлы между Windows / Linux, все будет в порядке.

Однако во многих случаях вы должны прочитать оба соглашения в обеих скомпилированных программах. Это характерно для всех видов документов и некоторых сетевых протоколов. В этом случае я рекомендую следующую процедуру:

  1. Просканируйте \r или \n.
  2. Если найденный символ \r, также ищите \n сразу после него. Если он существует, используйте его как часть той же новой строки.

Эта процедура сканирования принимает файлы с окончанием строк CR, LF и CR+LF. Это аналогично тому, что делают многие потоки строк более высокого уровня с обнаружением кодирования.

Вот еще один ответ, описывающий эту процедуру в коде для istream: Получение std :: ifstream для обработки LF, CR и CRLF?

person VoidStar    schedule 09.04.2015
comment
Есть ли другой символ разрыва строки? - person Tio Plato; 09.04.2015
comment
Другие существуют, см. en.wikipedia.org/wiki/Newline. Но, IMO, они не заслуживают поддержки. CR, LF и CR+LF - большая тройка для общей многоплатформенной поддержки. - person VoidStar; 09.04.2015