В чем разница между \r и \n?
Как \r
а также \n
разные? Я думаю, что это как-то связано с Unix против Windows против Mac, но я не уверен точно, чем они отличаются и что искать / сопоставлять в регулярных выражениях.
9 ответов
Они разные персонажи. \r
возврат каретки, и \n
это перевод строки.
На "старых" принтерах, \r
отправил печатающую головку обратно в начало строки и \n
выдвинул бумагу на одну строку. Поэтому оба были необходимы, чтобы начать печать на следующей строке.
Очевидно, что сейчас это не имеет значения, хотя в зависимости от консоли вы все еще можете использовать \r
перейти к началу строки и перезаписать существующий текст.
Что еще более важно, Unix имеет тенденцию использовать \n
в качестве разделителя строк; Windows имеет тенденцию использовать \r\n
в качестве разделителя строк и Mac (до OS 9), используемых для использования \r
в качестве разделителя строк. (Mac OS X - Unix-y, поэтому использует \n
вместо; могут быть некоторые ситуации совместимости, когда \r
вместо этого используется.)
Для получения дополнительной информации см. Статью Wikipedia newline.
РЕДАКТИРОВАТЬ: Это зависит от языка. В C# и Java, например, \n
всегда означает Unicode U+000A, который определяется как перевод строки. В C и C++ вода несколько мутнее, поскольку значение зависит от платформы. Смотрите комментарии для деталей.
В C и C++, \n
это концепция, \r
это персонаж, и \r\n
(почти всегда) ошибка переносимости.
Подумайте о старом телетайпе. Печатающая головка расположена на некоторой строке и в некотором столбце. Когда вы отправляете печатный символ в телетайп, он печатает символ в текущей позиции и перемещает голову к следующему столбцу. (Концептуально это аналогично пишущей машинке, за исключением того, что пишущие машинки обычно перемещают бумагу относительно печатающей головки.)
Когда вы хотели закончить текущую строку и начать со следующей строки, вам нужно было сделать два отдельных шага:
- переместите печатающую головку обратно в начало строки, затем
- переместите его вниз на следующую строку.
ASCII кодирует эти действия в виде двух разных управляющих символов:
\x0D
(CR) перемещает печатающую головку обратно в начало строки. (Юникод кодирует это какU+000D CARRIAGE RETURN
.)\x0A
(LF) перемещает печатающую головку вниз на следующую строку. (Юникод кодирует это какU+000A LINE FEED
.)
Во времена телетайпов и ранних технологических принтеров люди фактически использовали тот факт, что это были две отдельные операции. Отправив CR, не следуя за ним через LF, вы можете печатать поверх уже напечатанной строки. Это позволило такие эффекты, как акценты, жирный шрифт и подчеркивание. Некоторые системы несколько раз печатали, чтобы пароли не отображались в печатном виде. На ранних последовательных терминалах CRT CR был одним из способов управления положением курсора для обновления текста, уже находящегося на экране.
Но в большинстве случаев вы просто хотели перейти на следующую строку. Вместо того, чтобы требовать пару управляющих символов, некоторые системы допускают только один или другой. Например:
- Варианты Unix (включая современные версии Mac) используют только символ LF для обозначения новой строки.
- Старые (до OSX) файлы Macintosh использовали только символ CR для обозначения новой строки.
- VMS, CP / M, DOS, Windows и многие сетевые протоколы по- прежнему ожидают и того, и другого: CR LF.
- Старые системы IBM, которые использовали EBCDIC, стандартизированный по NL- символ, которого даже нет в наборе символов ASCII. В Unicode NL является
U+0085 NEXT LINE
, но фактическое значение EBCDIC0x15
,
Почему разные системы выбрали разные методы? Просто потому, что не было универсального стандарта. Там, где ваша клавиатура, вероятно, говорит "Enter", на старых клавиатурах говорилось "Return", что было коротким для возврата каретки. Фактически, на последовательном терминале нажатие Return фактически отправляет символ CR. Если бы вы писали текстовый редактор, было бы заманчиво использовать тот символ, который поступил из терминала. Возможно, поэтому старые Mac использовали только CR.
Теперь, когда у нас есть стандарты, есть больше способов представить разрывы строк. Хотя Unicode очень редко встречается в дикой природе, в нем есть новые символы, такие как:
U+2028 LINE SEPARATOR
U+2029 PARAGRAPH SEPARATOR
Еще до появления Unicode программисты хотели простые способы представления некоторых наиболее полезных управляющих кодов, не беспокоясь о базовом наборе символов. C имеет несколько escape-последовательностей для представления управляющих кодов:
\a
(для предупреждения), который звонит в телетайп или звонит терминалу\f
(для подачи формы), который перемещается в начало следующей страницы\t
(для вкладки), которая перемещает печатающую головку в следующую горизонтальную позицию вкладки
(Этот список намеренно неполон.)
Это отображение происходит во время компиляции- компилятор видит \a
и помещает любую магическую ценность, используемую, чтобы позвонить в звонок.
Обратите внимание, что большинство этих мнемоник имеют прямые корреляции с управляющими кодами ASCII. Например, \a
будет отображаться в 0x07 BEL
, Компилятор может быть написан для системы, которая использует что-то отличное от ASCII для набора символов хоста (например, EBCDIC). Большинство контрольных кодов, которые имели определенную мнемонику, могут быть сопоставлены с контрольными кодами в других наборах символов.
Ура! Переносимость!
Ну, почти. В C я мог бы написать printf("\aHello, World!");
который звонит в колокол (или издает звуковой сигнал) и выводит сообщение. Но если бы я захотел напечатать что-то на следующей строке, мне все равно нужно было бы знать, что требуется платформе хоста для перехода к следующей строке вывода. CR LF? CR? LF? NL? Что-то другое? Так много для мобильности.
C имеет два режима ввода / вывода: двоичный и текстовый. В двоичном режиме все отправленные данные передаются как есть. Но в текстовом режиме есть перевод во время выполнения, который преобразует специальный символ в то, что требуется платформе хоста для новой строки (и наоборот).
Отлично, так в чем же особенность?
Ну, это тоже зависит от реализации, но есть независимый от реализации способ указать это: \n
, Обычно это называется символом новой строки.
Это тонкий, но важный момент: \n
отображается во время компиляции в определенное для реализации значение символа, которое (в текстовом режиме) затем снова отображается во время выполнения на фактический символ (или последовательность символов), требуемый базовой платформой для перехода на следующую строку.
\n
отличается от всех других литералов обратной косой черты, потому что здесь задействованы два отображения. Это двухступенчатое отображение делает \n
значительно отличается от даже \r
, который является просто отображением времени компиляции в CR (или наиболее похожим управляющим кодом в любом базовом наборе символов).
Это сбивает с толку многих программистов на C и C++. Если бы вы опросили 100 из них, по крайней мере 99 скажет вам, что \n
означает перевод строки. Это не совсем правда. Большинство (возможно, все) реализаций C и C++ используют LF в качестве магического промежуточного значения для \n
но это деталь реализации. Компилятор может использовать другое значение. На самом деле, если набор символов хоста не является расширенным набором ASCII (например, если это EBCDIC), то \n
почти наверняка не будет LF.
Итак, в C и C++:
\r
буквально возврат каретки.\n
является магическим значением, которое переводится (в текстовом режиме) во время выполнения в / из семантики новой строки платформы хоста.\r\n
почти всегда ошибка переносимости. В текстовом режиме это переводится в CR, за которым следует последовательность новой строки платформы - вероятно, не то, что предполагалось. В двоичном режиме это переводится в CR, за которым следует некое магическое значение, которое может не быть LF- возможно, не тем, что предполагалось.\x0A
является наиболее переносимым способом обозначения ASCII LF, но вы хотите делать это только в двоичном режиме. Большинство реализаций в текстовом режиме будут воспринимать это как\n
,
- "\r" => Возврат
"\n" => Новая строка или перевод строки (семантика)
Системы на основе Unix используют просто "\ n" для окончания строки текста.
- Dos использует "\r\n" для окончания строки текста.
- Некоторые другие машины использовали просто "\r". (Commodore, Apple II, Mac OS до OS X и т. Д.)
\r
используется для указания на начало строки и может заменить текст оттуда, например
main()
{
printf("\nab");
printf("\bsi");
printf("\rha");
}
Производит этот вывод:
hai
\n
для новой линии.
Короче говоря, \r имеет значение ASCII 13 (CR), а \n имеет значение ASCII 10 (LF). Mac использует CR в качестве разделителя строк (по крайней мере, раньше, я не уверен для современных macs), *nix использует LF, а Windows использует оба (CRLF).
В дополнение к ответу @Jon Skeet:
Традиционно Windows использовала \r\n, Unix \n и Mac \r, однако более новые Mac используют \ n, поскольку они основаны на Unix.
\r - возврат каретки; \n - это новая строка (перевод строки) ... зависит от того, что означает каждая из ОС. Прочитайте эту статью, чтобы узнать больше о разнице между '\n' и '\r\n' ... в C.
Используется для возврата каретки. (Значение ASCII равно 13) \n используется для новой строки. (Значение ASCII равно 10)