Вопрос

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

Это было полезно?

Решение

Это разные персонажи. \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) перемещает печатающую головку обратно в начало строки.(Юникод кодирует это как U+000D CARRIAGE RETURN.)
  • \x0A (LF) перемещает печатающую головку вниз на следующую строку.(Юникод кодирует это как U+000A LINE FEED.)

Во времена телетайпов и ранних принтеров люди фактически пользовались тем фактом, что это были две отдельные операции.Отправляя CR без последующего LF, вы можете печатать поверх уже напечатанной строки.Это позволяло использовать такие эффекты, как акценты, жирный шрифт и подчеркивание.В некоторых системах надпечатка выполняется несколько раз, чтобы пароли не были видны в печатном виде.На первых последовательных ЭЛТ-терминалах CR был одним из способов управления положением курсора для обновления текста, уже находящегося на экране.

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

  • Варианты Unix (включая современные версии Mac) используют только символ LF для обозначения новой строки.
  • В старых файлах Macintosh (до OSX) для обозначения новой строки использовался только символ CR.
  • VMS, CP/M, DOS, Windows и многие другие. сетевые протоколы все еще ожидайте обоих:ЧР ЛФ.
  • Старые системы IBM, в которых использовались EBCDIC стандартизирован в NL — символ, которого даже не существует в наборе символов ASCII.В Юникоде NL — это U+0085 NEXT LINE, но фактическое значение EBCDIC равно 0x15.

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

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.
  • " " => Вернуть
  • " " => Перевод строки (семантика)

  • Системы на базе Unix используют просто " " в конце строки текста.

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

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

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

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

Производит этот вывод:

hai

\n для новой строки.

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

Традиционно Windows использовала , Unix и Mac , однако новые компьютеры Mac используют , поскольку они основаны на Unix.

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

— возврат каретки;  — новая строка (перевод строки)...Что означает каждый из них, зависит от ОС.Прочитай это статья подробнее о разнице между ' ' и ' '...в С.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top