В чем разница между r и n?


Как r и n другое? Я думаю, что это имеет какое-то отношение к Unix против Windows против Mac, но я не уверен точно, как они отличаются, и что искать/сопоставлять в регулярных выражениях.

9 208

9 ответов:

это разные персонажи. \r возврат каретки, и \n это линия.

на "старом" принтеры \r отправлено печатающую головку обратно в начало строки, и \n продвинул бумагу на одну строку. Поэтому оба были необходимы, чтобы начать печать на следующей строке.

очевидно, что это несколько неуместно сейчас, хотя в зависимости от консоли вы все еще можете использовать \r перейти к началу строки и заменить существующий текст.

что еще более важно, Unix имеет тенденцию использовать \n в качестве разделителя строк; Windows имеет тенденцию использовать \r\n как разделитель строк и Mac (до OS 9)используется использовать \r как разделитель строк. (Mac OS X-это Unix-y, поэтому использует \n вместо этого; там могут быть некоторые ситуации, совместимости, где \r используется вместо этого, хотя.)

для получения дополнительной информации см. новая статья Википедии.

редактировать: это чувствительный к языку. В C# и Java, например, \nвсегда означает Unicode U + 000A, который определяется как перевод строки. В C и C++ вода несколько мутнее, так как значение зависит от платформы. См. комментарии для деталей.

в C и C++, \n - Это концепция, \r - это символ, а \r\n это (почти всегда) ошибка переносимости.

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

когда вы хотели закончить текущую строку и начать на следующей строке, вы должны были сделать два отдельных шага:

  1. переместить печатающую головку обратно в начало строки, затем
  2. переместите его на следующую строку.

ASCII кодирует эти действия как два различных управляющих символа:

  • \x0D (CR) возвращает печатающую головку в начало строки. (Unicode кодирует это как U+000D CARRIAGE RETURN.)
  • \x0A (LF) перемещает печатающую головку вниз к следующей строке. (Unicode кодирует это как 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. В Юникоде NL-это U+0085 NEXT LINE, но фактическое значение EBCDIC 0x15.

почему разные системы выбирают разные методы? Просто потому, что не было универсального стандарта. Там, где ваша клавиатура, вероятно, говорит "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? КР? ЛФ? НЛ? Что-то еще? Так много для переносимости.

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 с последующим некоторым магическим значением, которое не может быть ЛФ -- возможно, не то, что задумано.
  • \x0A Это самый портативный способ указать ASCII LF, но вы хотите сделать это только в двоичном режиме. Большинство текстовых реализаций будут рассматривать это как \n.
  • "\r " = > Return
  • "\n " = > новая строка или перевод строки (семантика)

  • системы на базе Unix используют только "\n", чтобы закончить строку текста.

  • Dos использует "\r\n " для завершения строки текста.
  • некоторые другие машины использовали только "\r". (Commodore, Apple II, Mac OS до OS X и т. д..)

короче говоря \r имеет значение ASCII 13 (CR) и \n имеет значение ASCII 10 (LF). Mac использует CR в качестве разделителя строк (по крайней мере, это было раньше, я не уверен для современных Mac), *nix использует LF, а Windows использует оба (CRLF).

\r используется для указания на начало строки и может заменить текст, например

main()
{
printf("\nab");
printf("\bsi");
printf("\rha");
}

производит этот выход:

hai

\n для новой линии.

в дополнение к ответу @Jon Skeet:

традиционно Windows использовала \r\n, Unix \n и Mac \r, однако более новые Mac используют \n, поскольку они основаны на unix.

в C# я обнаружил, что они используют \r\n в строке.

\r-возврат каретки; \n-новая строка (подача строки)... зависит от ОС относительно того, что каждый означает. Прочтите это статьи подробнее о разнице между '\n' и '\r\n'... в с.

\r используется для возврата каретки. (Значение ASCII равно 13) \N используется для новой строки. (Значение ASCII равно 10)