Різниця між '\ n' і '\ r \ n'


99

Да да, я знаю , що '\n'пише новий рядок в UNIX в той час як для Windows , існує послідовність два символу: '\r\n'. Все це дуже добре в теорії, але моє питання чому ? Чому символ повернення каретки є додатковим у Windows? Якщо UNIX може це зробити, \nчому для цього потрібні два символи Windows?

Я читаю книгу Пітона Девіда Бізлі, і він говорить:

Наприклад, у Windows написання символу '\ n' фактично виводить двосимвольну послідовність '\ r \ n' (а при читанні файлу назад, \ \ r \ n 'переводиться назад в єдиний' \ n ' персонаж).

Навіщо зайвих зусиль?

Буду чесним. Я знаю різницю давно, але ніколи не намагався запитати ЧОМУ. Я сподіваюся, що сьогодні відповіли.

Дякую за ваш час.


5
Слід також зазначити, що Windows не єдина, яка використовує \r\n. Він також використовується більшістю текстових інтернет-протоколів (наприклад, SMTP, HTTP тощо) здебільшого з тієї ж причини, що і Windows (тобто історія).
Дін Хардінг

3
Крім того, перебуваючи в Java та використовуючи рядки формату (наприклад, System.out.printf()або String.format()), переконайтеся, що ви використовуєте %nяк CRLF для сумісності з ОС. \nзастаріло.
Гері Роу

Я бачив \n\rкілька разів. (Я думаю, це було щось від NetWare.)
grawity


1
Існує дуже мало програм для Windows, які фактично вимагають CRLF. CRLF може бути за замовчуванням, але майже все автоматично визначить і використовуватиме LF просто чудово. У мене всі текстові редактори в Windows налаштовані використовувати LF для всіх нових файлів, і це справді не проблема.
Кевін

Відповіді:


124

Зворотна сумісність.

Windows назад сумісний з MS-DOS (навіть агресивно), і MS-DOS використовував конвенцію CR-LF, оскільки MS-DOS був сумісний з CP / M-80 (дещо випадково), який використовував конвенцію CR-LF, тому що як ти загнав принтер (адже принтери спочатку були машинними машинками).

Принтери мають окрему команду для переміщення паперу вгору на один рядок до нового рядка та окрему команду для повернення каретки (куди було встановлено папір) назад до лівого поля.

Ось чому. І так, це прикро, але це частина пакетної угоди, яка дозволила MS-DOS перемогти CP / M, а Windows 95 перемогти над усіма іншими графічними інтерфейсами поверх DOS, а Windows XP взяти на себе з Windows 98.

(Примітка. Сучасні лазерні принтери все ще мають ці команди, оскільки вони також сумісні з попередніми принтерами, зокрема, HP це робить добре)

Для тих, хто не знайомий із машинками, ось відео, яке показує, як робилося введення тексту: http://www.youtube.com/watch?v=LJvGiU_UyEQ . Зауважте, що папір спочатку переміщується вгору, а потім каретка повертається, навіть якщо це відбувається простим рухом. Дінг сповістив друкарку, що кінець вже близький, і підготуватися до нього.


3
Як Unix зі своїм \ n використовувався лише для роботи із тим принтером старих часів? Я припускаю, що вони мали підключені Unix консолі до друкарських машинок типу?
Шентіл Кумаран

3
@Senthil, в Unix символ нового рядка перетворюється кінцевим драйвером. Це просто інше дизайнерське рішення.

2
@Senthil, якщо бути точним, в Unix принтери та термінали абстрагуються в операційній системі, і їх опис визначає, які послідовності байтів створюються для пристрою. У CP / M не було такої абстракції, і все це було запущено програмою - це, швидше за все, тому, що це було потрібно не всім програмам, тому наявність її в резидентній операційній системі забирає дорогоцінну пам'ять у програм, які цього не потребують. Пам'ятайте, що CP / M був розроблений для 16- кілобайтної системи.

1
"Отже, основна конструктивна особливість того, що, можливо, найдосконаліша транспортна система в світі, спочатку визначалася шириною дупи коня". Так і з програмним забезпеченням. astrodigital.org/space/stshorse.html
Ryan Michela

1
@Ryan, міська легенда. Розгорнуто

20

Наскільки мені відомо, це відноситься до часів друкарських машинок.

\r це повернення вагона, яке рухається там, де ви набираєте сторінку наліво (або праворуч, якщо це ваша культура)

\n це новий рядок, який переміщує ваш папір вгору.

Виконання лише однієї з них на друкарській машинці поставить вас у неправильне місце, щоб почати писати новий рядок тексту.

Коли з'явилися комп'ютери, я здогадувався, що деякі люди зберігали стару модель, але інші зрозуміли, що це не потрібно, і вклали повний новий рядок як один символ.


7
То чому Windows все ще дотримується цього?
sukhbir

8
Зворотна сумісність. Уявіть, скільки текстових документів порушиться, якби вони змінилися зараз
Метт Еллен

4
Власне кажучи, "незвичайним" тут є unixoid "використовувати тільки новий рядок", спочатку робиться (я вважаю), щоб зменшити кількість збережених символів (переклад на CR LF робиться в драйвері терміналу, це прапор 'onlcr' що контролює його для виведення
Ватін

3
У Windows був попередник з назвою DOS, який мав такий самий рядок. Windows зберегла сумісність. DOS мав своїх попередників, а саме CP / M. Це також використовувало CRLF. DOS зберігав сумісність. На розвиток CP / M вплинули TOPS DECs. І ви можете здогадатися, який lineending вони використовували. :-) Порівнянність багато що пояснює.
Менмент

5
Гаразд, але чому "Блокнот" все ще не розпізнає закінчення рядка "\ n"?
dan04

8

Я не знаю, чи це загальновідомі відомості, але слід зазначити, що CR все ще розуміють сучасні емулятори терміналів:

$ printf "hey world\rsup\n"
sup world

Це зручно для показників прогресу, наприклад

for i in {1..100}
do
    printf "\rLoading... %d%%" $i
    sleep 0.01
done
echo

1
На старих лінійних принтерах IBM (наприклад, 1403) угода полягала в тому, щоб розглянути перший символ лінійного буфера як символ керування кареткою. Пустий означав просування на одну лінію та друк. Плюс означав пропускати пробіли, і він використовувався, наприклад, для підкреслення. Нуль означав подвійний простір, а мінус - потрійний простір. «1», розташований у верхній частині наступної сторінки, та інші цифри переходять у визначені користувачем вертикальні позиції (використовуються для заповнення попередньо роздрукованих форм).
Джордж

7

Історично подання рядків означало, що валик - валик, на якому ви вводите - обертає один рядок, внаслідок чого текст з’являється у наступному рядку ... але в наступному стовпці.

Повернення каретки означало "повернення біта, з яким ви набираєте, на початок рядка".

Windows використовує CR + LF тому, що це робив MS-DOS, тому що CP / M це робив, тому що це мало сенс для послідовних ліній.

Unix скопіював свою \ n конвенцію, оскільки "Multics" це зробив.

Я підозрюю, що якщо викопати досить далеко назад, ви знайдете політичну незгоду між виконавцями!

(Ви залишили додатковий розважальний біт, де умовою Mac є (або раніше) просто використовувати CR для розділення рядків. А зараз у Unicode є власний роздільник ліній, U + 2028!)


Оце Так! не знав про Mac ...
Michael K

Я не впевнений, що ви знайдете політичну незгоду. Можливо також, що ви знайдете людей, які роблять подібні речі самостійно.
Девід Торнлі

1
Коли беруть участь різні органи зі стандартів? Я був би здивований, що не знаходжу політичних причин!
Френк Ширар

6

Історія персонажа нового рядка (Вікіпедія):

ASCII розроблявся одночасно ISO та ASA, організацією-попередником ANSI. У період 1963–1968 рр. Проекти проектів стандартів ISO підтримували використання як CR + LF, так і LF в якості нового рядка, тоді як проекти проекту ASA підтримували лише CR + LF.

Послідовність CR + LF була загальноприйнятою для багатьох ранніх комп'ютерних систем, які прийняли телетипні машини, як правило, ASR33, як консольний пристрій, оскільки ця послідовність була необхідна для розміщення цих принтерів на початку нового рядка. У цих системах текст часто був звичайно складений таким чином, щоб він був сумісний з цими принтерами, оскільки концепція драйверів пристроїв, які приховували такі деталі обладнання, не була ще добре розроблена; програми повинні були безпосередньо спілкуватися з телевізійною машиною та дотримуватися її домовленостей.

Розмежування двох функцій приховувало той факт, що друкована головка не могла повернутися з крайнього правого краю на початок наступного рядка за один символ. Ось чому послідовність завжди надсилалася спочатку з CR. Насправді, часто доводилося надсилати зайві символи (сторонні CR або NUL, які ігноруються), щоб дати друкованій головці час перейти до лівого поля.

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

MS-DOS (1981) прийняв CR + L CR + LF; Використання CR + LF CP / M має сенс для використання комп'ютерних терміналів через послідовну лінію. Ця конвенція успадкувала пізніша операційна система Microsoft.

Операційна система Multics почала розробку в 1964 році і використовувала лише LF як новий рядок. Unix дотримувався практики Multics, а пізніше системи слідували за Unix.


На старому терміналі-клавіатурі принтера IBM 2741 компонент принтера являв собою кулькову друкарську машину відбивного типу IBM Selectric. Зміна на великі регістри призвела до обертання кулі, забираючи додатковий час. У коді символів EBCDIC великі символи мали 1 біт у положенні 6. Отже, пробіл EBCDIC (0x40) був великим регістром! Якщо ви друкували довгий документ (наприклад, дипломну роботу), ви могли б істотно прискорити виведення, переклавши пробіли між малими словами в NUL або нижні пробіли (вони використовували інший символ, IL, якщо пам'ять служить, щоб ввести необхідні затримки, наприклад , при поверненні або вкладці).
Джордж

5

Що з людьми запитують "чому Unix може робити, \nа не Windows"? Це таке дивне питання.

  1. ОС майже нічого спільного з цим не має. Це більше питання про те, як додатки, бібліотеки, протоколи та формати файлів справляються з речами. За винятком випадків, коли ОС читає / записує текстові команди конфігурації чи команди командного рядка, не має сенсу бракувати ОС.
  2. Більшість програм для Windows можуть читати як \nі \r\nчудово. Вони також виходять, \r\nщоб усі були задоволені. Програма не просто «робить» або \nабо \r\n- вона приймає одне, друге або те і інше, і виводить одне, друге або те і інше.
  3. Як програміст це насправді майже ніколи не повинно вас турбувати. Практично кожна мова / платформа має можливість записувати правильний кінцевий рядок і читати найбільш грубо. Єдиний раз, коли мені довелося зіткнутися з проблемою, це було, коли я написав HTTP-сервер - і це було тому, що певний браузер (підказка: наступний найпопулярніший браузер після IE) робив \nзамість правильного \r\n .
  4. Набагато більш актуальне питання полягає в тому, чому так багато сучасних додатків Unix \nвидаються лише повністю знаючи, що існують деякі протоколи та програми, які їм не подобаються?

3
Ще одне актуальне питання: оскільки багато протоколів були розроблені в основному на системах Unix, чому вони не використовували '\ n'?
Девід Торнлі

@DavidThornley Оскільки \ r \ n швидше працює міжплатформенною (\ r для старих Mac, \ r \ n для Windows та \ n для * nix).
Основні

4

Причина, яку конвенції мають у своїх різних системах (\ n для систем типу Unix, \ r \ n для Windows тощо), полягає в тому, що після вибору конвенції ви не можете її змінювати, не порушуючи купу файлів людей. І це взагалі нахмурилося.

Системи типу Unix були розроблені (дуже рано) з використанням різних моделей телетипів, і в якийсь момент хтось вирішив, що обладнання повинно повертатися до вагона, коли воно здійснювало подачу ліній.

Windows прийшов з DOS, тому для Windows питання справді таке: Чому DOS використовував цю послідовність cr / lf? Я здогадуюсь, що це має щось спільне з CP / M, де DOS має коріння. Знову, певні моделі телетайпу, можливо, зіграли певну роль.


Хм цікаво.
сухбір

1
Чому Windows не може обробляти лінії, що закінчуються \n, але продовжують використовувати їх \r\nзараз? Якщо вони зробили це, починаючи з Windows XP, вони могли б тепер починати зберігати файли, \nа не \r\n.
Невдоволений голод

1
Windows нічого спільного з цим не має. Це рішення додатків, і більшість програм прочитають і \ \ n ', і \ \ \ \ \', і напишуть \ \ r \ n '- тому всі щасливі.
Рей Міясака

2

Ось відповідь з найкращого джерела - Microsoft. Чому лінійний термінатор CR + LF?

Цей протокол бере свій початок ще з часів телерайтсменів. CR означає «повернення каретки» - символ керування CR повернув друкуючу голівку («карету») у стовпчик 0, не просуваючи папір. LF позначає "linefeed" - символ управління LF просунув папір на одну лінію, не переміщуючи друкуючу головку. Тож якщо ви хотіли повернути друкуючу голівку до нульового стовпця (готовий до друку наступного рядка) і просунути папір (щоб він друкувався на свіжому папері), вам потрібні і CR, і LF.

Якщо ви перейдете до різних документів Інтернет-протоколів, таких як RFC 0821 (SMTP), RFC 1939 (POP), RFC 2060 (IMAP) або RFC 2616 (HTTP), ви побачите, що всі вони визначають CR + LF як послідовність завершення рядка Отже, справжнє питання не "Чому CP / M, MS-DOS і Win32 використовують CR + LF як термінатор лінії?" а швидше "Чому інші люди вирішили відрізнятись від цих стандартних документів і використали інший лінійний термінатор?"

Unix прийняла звичайний LF як послідовність завершення рядків. Якщо ви подивитеся на варіанти stty, ви побачите, що опція onlcr вказує, чи слід змінити LF на CR + LF. Якщо ви невірно встановили це налаштування, ви отримаєте текст сходів, куди

each
    line
        begins

де попередній рядок відключений. Тож навіть Unix, залишаючи в режимі «необроблений», вимагає CR + LF для припинення рядків. Неявна CR перед LF - це unix винахід, ймовірно, як економія, оскільки вона економить один байт на рядок.

Unix родовід мови С переніс цю конвенцію в стандарт мови C, що вимагає лише "\ n" (який кодує LF) для завершення рядків, що покладає тягар на бібліотеки виконання, щоб перетворити необроблені файлові дані в логічні рядки.

Мова С також ввела термін "нова лінія" для вираження поняття "загальний термінатор лінії". Мені кажуть, що комітет ASCII змінив ім'я символу 0x0A на "новий рядок" близько 1996 року, тому рівень плутанини піднявся ще вище.

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