Как \ n и \ r обрабатываются по-разному в Linux и Windows?

77023
千里ちゃん

Я думаю, \nперемещает иглу вниз, и \rперемещает иглу в начало линии (выравнивание по левому краю)? Я не уверен, хотя. Так что, если я ошибаюсь, поправьте меня ...

Во всяком случае, мне сказали, что для Windows и Linux ручки newlinesи carriage returnsиначе. Я хотел бы знать, как они относятся к ним по-разному и в некоторых местах, где важно помнить. Спасибо за ответы.

17
До сих пор я знаю, что `\ r \ n` - это нормально в Windows, но` \ n \ r` - нет, и я помню это, потому что `\ r \ n` является аббревиатурой для зарегистрированной медсестры. Я также слышал, что `\ n` - это то, что люди используют в Linux, и` \ r` не используется отдельно для той же цели, что и `\ r \ n`. `\ r` используется в действительно старых MacOS. Я не проверял эти факты, хотя. 千里ちゃん 12 лет назад 0
Не называйте их `\ r` и` \ n`, поскольку то, как обрабатывается `\ n`, зависит от того, где вы его используете. Лучше называть их `CR` и` LF`. Ignacio Vazquez-Abrams 12 лет назад 3
Игнасио, эти аббревиатуры не имеют для меня значения. Как вы это называете: /? ОН ... ЛИНИЯ ПОДАЧА И ВОЗВРАТ ПЕРЕВОЗКИ Спасибо, слеске. 千里ちゃん 12 лет назад 0
@ IgnacioVazquez-Abrams - это не то же самое, что LF? На любом ASCII-графике не является ли символ 13 = \ n = LF? barlop 12 лет назад 0
@barlop: не в C при выводе в Windows. Ignacio Vazquez-Abrams 12 лет назад 1
@ IgnacioVazquez-Abrams C не переписывает таблицу ASCII. Я согласен, \ n может не работать как перевод строки, но это не значит, что это не символ LF. (больше вопросов, поскольку я знаю, что вы знаете больше, чем я) barlop 12 лет назад 0
@ IgnacioVazquez-Abrams \ n, вероятно, означает новую строку. то есть LF. Как они действуют - другое дело. В Unix \ n или LF в любом случае не просто перевод строки, он также выполняет функцию возврата каретки, но он все еще называется символом перевода строки. barlop 12 лет назад 0
@barlop: Чтобы быть совершенно справедливым, `\ n` не имеет никакого реального значения вне C (и других языков программирования, которые его интерпретируют). Последовательность символов "\ n" даже ничего бы не значила *, если бы не C. Ignacio Vazquez-Abrams 12 лет назад 0

3 ответа на вопрос

16
sleske

Я думаю, что \ n перемещает стрелку вниз, а \ r перемещает стрелку к началу строки (выравнивание по левому краю)? Я не уверен, хотя

Это правда, более или менее, но в основном историческое любопытство. Первоначально, подача строки (LF) использовалась, чтобы продвинуть бумагу одной линией на принтерах и печатных терминалах ( телепринтеры ); возврат каретки (CR) вернул печатающую головку в начало строки.

Это, вероятно, все еще работает на современных принтерах, когда они используются в «текстовом режиме», но в остальном сегодня мало уместно.

Во всяком случае, мне сказали, что Windows и Linux по-разному обрабатывают переводы строки и возврат каретки.

Разница проста: разработчикам ОС пришлось выбирать, как представлять начало новой строки текста в компьютерных файлах. По различным историческим причинам в мире Unix / Linux в качестве маркера новой строки был выбран один символ LF; MS-DOS выбрал CR + LF, и Windows унаследовала это. Таким образом, разные платформы используют разные соглашения.

На практике это становится все меньше и меньше проблемой. Маркер новой строки действительно имеет отношение только к тем программам, которые обрабатывают «простой текст», и их не так много - он в основном влияет только на исходный код программы, файлы конфигурации и некоторые простые текстовые файлы с документацией. В настоящее время большинство программ, обрабатывающих файлы такого типа (редакторы, компиляторы и т. Д.), Могут обрабатывать оба соглашения новой строки, поэтому не имеет значения, какой из них вы выберете.

В некоторых случаях инструменты настаивают на «своем» соглашении о новой строке (например, сценарии оболочки Unix не должны использовать CR + LF), и в этом случае вы должны использовать правильный.

Та же самая линия вопросов: распознают ли языки программирования `\ n \ r` и` \ n` как одно и то же? Например, если бы я разбирал текстовый файл, который был отредактирован на чужом ПК и содержал как разрывы строк для Linux, так и для Windows, выполнение `preg_match` для` \ n` и `\ n \ r` давало бы мне другое Результаты? 千里ちゃん 12 лет назад 0
@ 千里 ち ゃ ん: Это полностью зависит от языка программирования, компилятора и т. Д. В частности, если вы используете регулярные выражения, это будет зависеть от используемого вами механизма регулярных выражений - некоторые различают разные окончания строк, некоторые - нет (большинство можно настроить в любом случае, Я верю). sleske 12 лет назад 0
@ 千里 ち ゃ ん: Если у вас есть вопрос о том, как какой-то системный язык / язык программирования / механизм регулярных выражений обрабатывает различные соглашения о переводе строки, просто задайте это как отдельный вопрос. sleske 12 лет назад 0
Вы должны писать \ r \ n не так, как вы. Что касается языков программирования, они могут читать отдельные символы, и вы, программист, можете видеть, какой из них используется для ввода, и вы, программист, можете также делать все, что захотите для вывода. Точно так же, как вы могли бы сказать «Пишите ABC, а затем \ r \ r \ r \ n» любые символы, которые вы хотите вставить в конце! некоторые другие символы не могут быть напечатаны и не могут быть графическими или как угодно. Они могут иметь некоторые встроенные функции, такие как println, и то, что они используют для своей новой строки, будет одной или другой, это не может быть и то и другое. barlop 12 лет назад 0
@ 千里 ち ゃ ん и некоторые языки программирования могут позволять вам выбрать, какой конец строки может быть задан в одной из их встроенных функций, так что даже в встроенной функции вы можете ... теоретически в любом случае. +, как уже упоминалось, на практике вы можете написать любой конец строки, какой захотите ... хотя вы не сможете сделать это так эффективно, как с помощью функции println. barlop 12 лет назад 0
За исключением регулярных выражений, большинство сред программирования, с которыми я работаю (и, вероятно, большинство нормальных сред программирования), будут решать эту проблему автоматически. Всегда используйте `\ n` сам по себе, и LF или CRLF будут выводиться в зависимости от того, что является правильным в текущей среде (или, черт возьми, LFCR, если вы находитесь на какой-то дурацкой Sun). Использование `\ r \ n` в программах является худшей идеей, потому что в компиляторах, с которыми я знаком, это приведет к CRLF в * nix (плохо) и CRCRLF в Windows (плохо). Java - единственное исключение, о котором я знаю (и я только вспомнил это, прочитав другой комментарий по этому вопросу). jcrawfordor 12 лет назад 0
Я изучал проблему с инструментами разработки Chrome, отладкой и точками останова (https://code.google.com/p/v8/issues/detail?id=2825#c33) и думаю, что это связано с тем, как переводятся строки обрабатываются инструментами chrome dev и как linux (в данном случае Git) их нормализует. seangwright 9 лет назад 0
11
RedGrittyBrick

CR и LF

В Американском стандартном коде для обмена информацией (ASCII) определены управляющие символы, включая CARRIAGE-RETURN (CR) и LINE-FEED (LF), которые использовались (и остаются) для управления положением печати на принтерах способом, аналогичным механические пишущие машинки, которые предшествовали ранним компьютерным принтерам.

Зависимость от платформы

В Windows традиционным разделителем строк в текстовых файлах является CR, за которым следует LF

В старых (до OSX) системах Apple Macintosh традиционным разделителем строк в текстовых файлах был CR

В Unix и Linux традиционным разделителем строк в текстовых файлах является LF.

\ n и \ r

Во многих языках программирования и сценариев \n означает «новая строка». Иногда (но не всегда) это означает символ ASCII LINE-FEED (LF), который, как вы говорите, перемещает курсор (или позицию печати) вниз на одну строку. В принтере или пишущей машинке это фактически сдвинет бумагу на одну строку вверх.

Неизменно \rозначает символ ASCII CARRIAGE-RETURN (CR), имя которого на самом деле происходит от механических пишущих машинок, где была клавиша возврата каретки, из-за которой валик («каретка»), по которому бумага перемещалась вправо, приводится в движение пружиной, насколько это возможно. Таким образом устанавливая текущую позицию набора текста на левом поле.

программирование

В некоторых языках программирования \nможет означать зависящую от платформы последовательность символов, которые заканчиваются или разделяют строки в текстовом файле. Например, в Perl, print "\n"производит другую последовательность символов в Linux, чем в Windows.

В Java, лучшая практика, если вы хотите использовать родные конец строки для платформы во время выполнения, не использовать \nили \rвообще. Вы должны использовать System.getProperty("line.separator"). Вы должны использовать \nи \rгде вы хотите LF и CR независимо от платформы (например, как используется в HTTP, FTP и других интернет-коммуникационных протоколах).

Unix stty

В оболочке Unix sttyкоманда может использоваться для перевода оболочки между этими различными соглашениями. Например stty -onlcr, заставит оболочку впоследствии перевести все исходящие LF в CR LF.

Linux и OSX следуют соглашениям Unix

Текстовые файлы

Текстовые файлы по-прежнему чрезвычайно важны и широко используются. Например, HTML и XML являются примерами текстового файла. Большинство важных интернет-протоколов, таких как HTTP, следуют соглашениям о текстовых файлах и содержат спецификации для окончаний строк.

Принтеры

Большинство принтеров, кроме самых дешевых, по-прежнему уважают CR и LF. На самом деле они являются основополагающими для наиболее широко используемых языков описания страниц - PCL и Postscript.

Примечание по Java: обычно не верно, что вы не должны использовать \ n или \ r вообще. Просто в Java "\ n" всегда LF, а "\ r" всегда CR. Это * может * быть именно тем, что вы хотите: если вы хотите определенный стиль окончания строки, используйте их; если вы явно хотите, чтобы исходная строка заканчивалась на компьютере, на котором вы работаете, * тогда * используйте `line.separator`. Это действительно зависит от того, что вы хотите. sleske 12 лет назад 1
И кстати, `println ()` автоматически использует `line.separator`, поэтому, если вы хотите использовать собственные окончания строк, вы можете использовать` println () `(и если вам нужен определенный конкретный тип окончания строки, то не используйте это, но используйте "\ n" и т. д. явно). sleske 12 лет назад 0
@Sleske: Хорошие моменты. Я обновлю свой ответ соответственно. RedGrittyBrick 12 лет назад 0
Существуют ли какие-либо языки или компиляторы, где `\ n` является управляющим символом, отличным от ASCII LF (кроме систем на основе EBCDIC)? Я имею в виду то, что `\ n` означает в строковом или символьном литерале, а не эффект отправки его в файл или устройство вывода. Keith Thompson 12 лет назад 1
@KeithThompson: Согласно [Wikipedia] (http://en.wikipedia.org/wiki/Newline#In_programming_languages) Стандарт C позволяет \ n быть представленным любым отдельным значением символа. RedGrittyBrick 12 лет назад 0
@RedGrittyBrick: с некоторыми ограничениями (например, он должен быть уникальным). Но мой вопрос был о реализации, а не о стандарте. Например, компилятор MacOS C до OSX * может * иметь `'\ n'` равным CR - но тогда`' \ r'` должен быть чем-то другим (LF?). Является ли `'\ n' == 10'` универсально верным для не-EBCDIC систем? (Конечно, хорошо написанный код не должен предполагать это.) Keith Thompson 12 лет назад 0
@KeithThompson: Для Java: Да, `\ n` всегда является кодом 10 ASCII (и Unicode), потому что JLS говорит об этом явно (JLS 3.10.6,« Escape-последовательности для символьных и строковых литералов »- я проверял :-)) , Для других языков - хороший вопрос. sleske 12 лет назад 1
@KeithThompson: рассмотрите вопрос об этом в качестве отдельного вопроса о SO. Это интересная проблема. sleske 12 лет назад 0
3
James Billingham

Короче, был нужен для принтеров, но сейчас ОС делают это немного по-другому. В большинстве случаев хорошо просто выполнять CR и LF, \r\nи в большинстве случаев это будет работать нормально.