Яка різниця між \ r та \ n?


245

Як \rі чим \nвідрізняються? Я думаю, що це має щось спільне з Unix проти Windows проти Mac, але я не впевнений, чим вони відрізняються, і що шукати / відповідати в регексах.


1
Для цього потрібен мовний тег. Різні мови мають різні тлумачення '\n'.
Адріан Маккарті

Відповіді:


383

Вони різні персонажі. \r- це повернення вагона, і \nце лінія подачі.

На "старих" принтерах \rвідправте друковану головку назад на початок рядка і \nпросунув папір на одну лінію. Тому обом було потрібно розпочати друк на наступному рядку.

Очевидно, що це дещо не має значення, хоча залежно від консолі ви все-таки зможете скористатися \rдля переходу до початку рядка та перезапису існуючого тексту.

Що ще важливіше, Unix прагне використовувати \nяк роздільник рядків; Windows , як правило , використовувати в \r\nякості роздільника рядків і Маков (до OS 9) , що використовується для використання в \rякості роздільника рядків. (Mac OS X є Unix-y, тому використовує \nнатомість; можуть бути деякі ситуації сумісності, коли \rзамість цього використовується.)

Для отримання додаткової інформації див статтю в новому рядку Вікіпедії .

EDIT: Це чутливо до мови. Наприклад, у C # та Java \n завжди означає Unicode U + 000A, який визначається як канал рядків. У C і C ++ вода дещо каламутніша, оскільки сенс залежить від платформи. Деталі див. У коментарях.


22
+1 для людей похилого віку. Вихід терміналу, який використовується для безпосереднього управління прославленим електронним терміналом (ваш TTY перед тими вигадливими дисплеями CRT). Отже, ми отримуємо чудові артефакти тих, хто повертається до вагони та символів нового рядка (обидва вони можуть знадобитися, як згадував Джон Скіт) та такі речі, як \ "дзвін", \ b "зворотний простір" (не плутати з "видалити" "), і всі інші контрольні символи, необхідні для спілкування з tty.
erjiang

35
Ще +1 для старих людей. Ви все одно можете натиснути Ctrl + G у командному рядку Windows, натисніть клавішу Enter, і динамік ПК пролунає звуковий сигнал. Це залишилося з давніх часів.
Дейв Карліл

@Crappy Кодування хлопець насправді? У Vista просто сказано, що "" "не розпізнається як внутрішня чи зовнішня команда"
Ponkadoodle

2
@AdrianMcCarthy: Звичайно, питання фактично не вказує на C або C ++. У C #, наприклад , \n є гарантовано нового рядка (розділ 2.4.4.4). Звичайно, було б добре, якби ОП вказала платформу ... Крім того, я думаю, що цей рівень деталізації був би більш заплутаним, ніж корисним для того, хто просто запитає про різницю.
Джон Скіт

2
@AdrianMcCarthy: Але в C # і Java , по крайней мере, вона є лінія подачі. Це U + 000A, яке Unicode названо "LINE FEED" (і NEW LINE). Я редагую, щоб згадати особливий випадок C та C ++, але я справді вважаю, що це особливі випадки, а не навпаки.
Джон Скіт

91

У 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. У Unicode NL є U+0085 NEXT LINE, але фактичне значення EBCDIC є 0x15.

Чому різні системи обрали різні методи? Просто тому, що не було універсального стандарту. Там, де на вашій клавіатурі, напевно, написано "Enter", старіші клавіатури раніше говорили "Return", що було коротким для Carriage Return. Насправді на послідовному терміналі натискання Return насправді надсилає символ CR. Якщо ви писали текстовий редактор, було б спокусити просто використовувати цей символ, як він прийшов з терміналу. Можливо, тому старіші Маки використовували просто CR.

Тепер, коли ми маємо стандарти , існує більше способів представити розриви рядків. Хоча в дикій природі вкрай рідкісний, Unicode має нових символів, таких як:

  • U+2028 LINE SEPARATOR
  • U+2029 PARAGRAPH SEPARATOR

Ще до того, як Unicode з'явився, програмісти хотіли простих способів представити деякі найкорисніші коди управління, не турбуючись про базовий набір символів. C має декілька послідовностей запуску для представлення контрольних кодів:

  • \a (для сповіщення), який дзвонить у дзвінок телетексту або робить сигнальний сигнал
  • \f (для подачі форми), яка переходить на початок наступної сторінки
  • \t (для вкладки), яка переміщує друкуючу голівку в наступне горизонтальне положення

(Цей список навмисно неповний.)

Таке відображення відбувається під час компіляції - компілятор бачить \aі ставить будь-яке магічне значення, яке використовується для дзвінка дзвона.

Зауважте, що більшість цих мнемоніків мають прямі кореляції з кодами управління ASCII. Наприклад, \aбуде карта з 0x07 BEL. Компілятор може бути записаний для системи, яка використовувала щось інше, ніж ASCII для набору символів хоста (наприклад, EBCDIC). Більшість контрольних кодів, які мали специфічну мнемоніку, можна було відобразити на контрольні коди в інших наборах символів.

Huzzah! Переносність!

Ну, майже. На мові C я міг написати, printf("\aHello, World!");який дзвонить у дзвінок (або звуковий сигнал) і видає повідомлення. Але якщо я хотів би потім надрукувати щось на наступному рядку, я все одно повинен знати, що потрібно для платформи хоста, щоб перейти до наступного рядка виводу. CR LF? CR? НЧ? 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це самий портативний спосіб вказати LF ASCII, але ви хочете робити це лише у двійковому режимі. Більшість текстових режимів реалізує подібне \n.

Подивився цей пост, намагаючись розібратися, як розділити <textarea> вхід на Python, і \r\nнасправді це єдиний спосіб, коли я міг правильно розділити рядки на окремі елементи списку. Мене змушує замислитися, чи це якийсь дивний артефакт HTML, чи це пов’язано з тим, як Python вводить рядок з мого requestоб'єкта.
Пат Джонс

11
  • "\ r" => Повернутись
  • "\ n" => Новий рядок або Зворотний рядок (семантика)

  • Системи на базі Unix використовують лише "\ n", щоб закінчити рядок тексту.

  • Dos використовує "\ r \ n", щоб закінчити рядок тексту.
  • Деякі інші машини використовували лише "\ r". (Commodore, Apple II, Mac OS до OS X тощо).

5

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

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

Виробляє цей вихід:

hai

\n призначений для нової лінії.


4

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


1
Системи Mac OS X використовують LF за замовчуванням (оскільки він заснований на BSD Unix).
dreamlax

3

Окрім відповіді @Jon Skeet:

Традиційно Windows використовує \ r \ n, Unix \ n та Mac \ r, однак новіші Mac використовують \ n як основу для Unix.



2

\ r повернення перевезення; \ n - Нова лінія (Посилання рядків) ... залежить від операційної системи щодо того, що означає кожен. Прочитайте цю статтю, щоб дізнатися більше про різницю між "\ n" та "\ r \ n" ... у C.


1

використовується для повернення вагона. (Значення ASCII дорівнює 13) \ n використовується для нового рядка. (Значення ASCII - 10)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.