Nowa linia
Pojęcia powrotu karetki (CR) i znaku nowego wiersza (LF) są ściśle powiązane i można je rozpatrywać osobno lub łącznie. W fizycznym nośniku, jakim są maszyny do pisania i drukarki, do utworzenia nowego wiersza na stronie potrzebne są dwie osie ruchu, „w dół” i „w poprzek”. Chociaż projekt maszyny (maszyna do pisania lub drukarka) musi uwzględniać je oddzielnie, abstrakcyjna logika oprogramowania może łączyć je w jedno zdarzenie. Dlatego znak nowego wiersza w kodowaniu znaków można zdefiniować jako CR
i LF
połączone w jeden (powszechnie nazywane CR + LF
lub CRLF
).
Niektóre zestawy znaków zapewniają oddzielny kod znaku nowej linii. Na przykład EBCDIC zawiera kod znaku NL oprócz kodów CR i LF. Unicode, oprócz dostarczania kodów kontrolnych ASCII CR i LF, zapewnia również kod kontrolny „następny wiersz” (NEL), a także kody kontrolne dla znaczników „separator linii” i „separator akapitu”.
- Systemy EBCDIC – głównie systemy mainframe IBM, w tym z / OS (OS / 390) i i5 / OS (OS / 400) – użyj NL (New Line, 0x15) jako znaku łączącego funkcje nowego wiersza i karetki powrót. Odpowiedni znak Unicode (
0x85
) nosi nazwę NEL (Next Line). EBCDIC ma również znaki sterujące zwane CR i LF, ale wartość liczbowa LF (0x25) różni się od tej używanej przez ASCII (0x0A). Ponadto niektóre warianty EBCDIC również używają języka NL, ale przypisują znakowi inny kod numeryczny. Jednak te systemy operacyjne używają systemu plików opartego na rekordach, który przechowuje pliki tekstowe jako jeden rekord w wierszu. W większości formatów plików w rzeczywistości nie są przechowywane żadne terminatory wierszy. - Systemy operacyjne serii CDC 6000 definiowały znak nowej linii jako dwa lub więcej znaków sześciobitowych o wartości zerowej na końcu 60-bitowego słowa. Niektóre konfiguracje definiowały również znak o wartości zerowej jako znak dwukropka, w wyniku czego wiele dwukropków może być interpretowanych jako znak nowej linii w zależności od pozycji.
- RSX-11 i OpenVMS również używają systemu plików opartego na rekordach , który przechowuje pliki tekstowe jako jeden rekord w wierszu. W większości formatów plików w rzeczywistości nie są przechowywane żadne terminatory linii, ale usługa Record Management Services może w przejrzysty sposób dodać terminator do każdej linii, gdy jest ona pobierana przez aplikację. Same rekordy mogą zawierać te same znaki terminatora linii, które mogą być uznane za funkcję lub uciążliwość w zależności od aplikacji. RMS nie tylko przechowywał rekordy, ale także przechowywał metadane o separatorach rekordów w różnych bitach, aby plik jeszcze bardziej komplikował sprawę (ponieważ pliki mogą mieć rekordy o stałej długości, rekordy z prefiksem liczby lub rekordy zakończone określonym znakiem ). Bity nie były „t ogólne”, więc chociaż mogli określić, że CRLF, LF lub nawet CR był terminatorem linii, nie mógł zastąpić innego kodu.
- Stała długość linii była używana przez niektóre wczesne komputery mainframe systemy. W takim systemie zakładano niejawny koniec linii, na przykład co 72 lub 80 znaków. Nie zapisano żadnego znaku nowej linii. Jeśli plik został zaimportowany ze świata zewnętrznego, linie krótsze niż długość linii musiały być wypełnione spacjami, natomiast linie dłuższe niż długość linii musiały zostać obcięte. To naśladowało użycie kart perforowanych, na których każdy wiersz był przechowywany na osobnej karcie, zwykle z 80 kolumnami na każdej karcie, często z numerami sekwencyjnymi w kolumnach 73–80. Wiele z tych systemów dodawało znak sterujący karetką na początku następnego rekordu; może to wskazywać, czy następny rekord był kontynuacją linii rozpoczętej przez poprzedni rekord, czy też nową linią, lub powinien nadrukować poprzednią linię (podobnie jak CR). Często był to zwykły drukowany znak, taki jak
#
, którego w związku z tym nie można było użyć jako pierwszego znaku w wierszu. Niektóre wczesne drukarki wierszowe interpretowały te znaki bezpośrednio w przesłanych do nich rekordach.
UnicodeEdit
Standard Unicode definiuje liczbę znaków, które zgodne aplikacje powinny rozpoznawać jako terminatory linii:
LF: Line Feed, U + 000A VT: Tabulator pionowy, U + 000B FF: Posuw formularza, U + 000C CR: Powrót karetki, U + 000D CR + LF: CR (U + 000D), a następnie LF (U + 000A) NEL: Następny wiersz, U + 0085 LS: Separator linii, U + 2028 PS: Separator akapitu, U + 2029
Może się to wydawać zbyt skomplikowane w porównaniu z podejściem takim jak konwersja wszystkich terminatorów linii na jeden znak, na przykład LF. Jednak Unicode został zaprojektowany, aby zachować wszystkie informacje podczas konwersji pliku tekstowego z dowolnego istniejącego kodowania na Unicode i odwrotnie. Dlatego Unicode powinien zawierać znaki zawarte w istniejących kodowaniach.NL jest zawarte w EBCDIC z kodem 0x15 i często odwzorowywane na NEL, który jest znakiem kontrolnym w zestawie kontrolnym C1. Jako taki jest zdefiniowany przez ECMA 48 i rozpoznawany przez kodowanie zgodne z ISO / IEC 2022 (co jest odpowiednikiem ECMA 35). Zestaw sterujący C1 jest również zgodny z ISO-8859-1. Podejście przyjęte w standardzie Unicode umożliwia transformację w obie strony zachowującą informacje, jednocześnie umożliwiając aplikacjom rozpoznawanie wszystkich możliwych typów terminatorów linii.
Rozpoznawanie i używanie kodów nowej linii większych niż 0x7F (NEL, LS i PS) nie jest często wykonywane. W UTF-8 są wielobajtowe, a kod NEL został użyty jako wielokropek (…
) w systemie Windows-1252. Na przykład:
- ECMAScript akceptuje LS i PS jako podziały wierszy, ale traktuje odstępy U + 0085 (NEL) zamiast podziału wiersza.
- Windows 10 nie traktuje żadnego z NEL, LS ani PS jako podziałów wierszy w swoim domyślnym edytorze tekstu, Notatniku.
- gedit, domyślny edytor tekstu środowiska graficznego GNOME , traktuje LS i PS jako znaki nowej linii, ale nie dla NEL.
- JSON dopuszcza znaki LS i PS w łańcuchach, podczas gdy ECMAScript przed ES2019 traktował je jako znaki nowej linii, a zatem niedozwoloną składnię.
- YAML nie rozpoznaje ich już jako specjalne od wersji 1.2, aby były zgodne z JSON.
Znaki Unicode U + 2424 (SYMBOL FOR NEWLINE, 
), U + 23CE (RETURN SYMBOL, ⏎
), U + 240D (SYMBOL DLA CARRIAGE RETURN, ␍
) i U + 240A (SYMBOL FOR LINE FEED, ␊
) są przeznaczone do prezentowania czytelnikowi dokumentu widocznego dla użytkownika znaku i dlatego nie są rozpoznawane jako nowy wiersz.
Sekwencje specjalneEdytuj
Sekwencja ucieczki to kombinacja znaków, które nie przedstawia tekstu; zamiast być wyświetlanym (jako tekst) ma zostać przechwycony przez program i ma zostać wykonana specjalna funkcja. Sekwencje specjalne są również używane do obsługi (ustawiania, wyszukiwania, zamiany itp.) Znaków specjalnych.
W językach programowaniaEdit
Aby ułatwić tworzenie przenośnych programów, języki programowania zapewniają pewne abstrakcje, aby radzić sobie z różnymi typami sekwencji nowej linii używanych w różnych środowiskach.
Język programowania C udostępnia sekwencje specjalne „\ n” (nowa linia) i „\ r” (powrót karetki). Jednak nie jest wymagane, aby były one równoważne ze znakami sterującymi ASCII LF i CR. Standard C gwarantuje tylko dwie rzeczy:
- Każda z tych sekwencji sterujących odwzorowuje na unikalny numer zdefiniowany w implementacji, który może być przechowywany w pojedynczej wartości znaku.
- Podczas pisania do pliku, węzła urządzenia lub gniazda / kolejki w trybie tekstowym, „\ n” jest przezroczysto tłumaczone na natywną sekwencję nowej linii używaną przez system, która może być dłuższa niż jeden znak. Podczas czytania w trybie tekstowym natywna sekwencja nowej linii jest tłumaczona z powrotem na „\ n”. W trybie binarnym nie jest wykonywane żadne tłumaczenie, a wewnętrzna reprezentacja utworzona przez „\ n” jest wyprowadzana bezpośrednio.
Na platformach Unix, gdzie pochodzi C, natywną sekwencją nowej linii jest ASCII LF ( 0x0A), więc „\ n” zostało po prostu zdefiniowane jako ta wartość. Ponieważ reprezentacja wewnętrzna i zewnętrzna są identyczne, tłumaczenie wykonywane w trybie tekstowym jest bezczynne, a Unix nie ma pojęcia trybu tekstowego ani trybu binarnego. To spowodowało, że wielu programistów, którzy tworzyli swoje oprogramowanie w systemach uniksowych, po prostu całkowicie zignorowało to rozróżnienie, w wyniku czego kod nie jest przenośny na różne platformy.
Funkcji fgets () z biblioteki C najlepiej unikać w trybie binarnym ponieważ każdy plik, który nie został napisany zgodnie z konwencją nowego wiersza systemu Unix, zostanie błędnie odczytany. Ponadto w trybie tekstowym każdy plik, który nie został zapisany z natywną sekwencją nowego wiersza systemu (np. Plik utworzony w systemie Unix, a następnie skopiowany do systemu Windows), również zostanie źle odczytany.
Inny częstym problemem jest użycie „\ n” podczas komunikacji przy użyciu protokołu internetowego, który nakazuje użycie ASCII CR + LF do kończenia wierszy. Zapisywanie „\ n” do strumienia w trybie tekstowym działa poprawnie w systemach Windows, ale generuje tylko LF w Unix i coś zupełnie innego w bardziej egzotycznych systemach. Używanie „\ r \ n” w trybie binarnym jest nieco lepsze.
Biblioteki Java I / O nie tłumaczą ich w sposób przejrzysty na zależne od platformy sekwencje nowej linii w dane wejściowe lub wyjściowe. Zamiast tego zapewniają funkcje do pisania pełnego wiersza, które automatycznie dodają natywną sekwencję nowego wiersza, oraz funkcje do czytania wierszy, które akceptują dowolny z CR, LF lub CR + LF jako terminator wiersza (zobacz BufferedReader.readLine () Metoda System.lineSeparator () może służyć do pobrania podstawowego separatora wierszy.
Przykład:
String eol = System.lineSeparator(); String lineColor = "Color: Red" + eol;
Python zezwala na „Universal Newline Support” podczas otwierania pliku do odczytu, kiedy importowanie modułów i wykonywanie pliku.
Niektóre języki stworzyły specjalne zmienne, stałe i podprocedury, aby ułatwić wprowadzanie znaków nowej linii podczas wykonywania programu. W niektórych językach, takich jak PHP i Perl, podwójne cudzysłowy są wymagane do wykonania podstawienia zmiany znaczenia dla wszystkich sekwencji specjalnych, w tym „\ n” i „\ r”. W PHP, aby uniknąć problemów z przenoszeniem, sekwencje nowej linii powinny być tworzone przy użyciu stałej PHP_EOL.
Przykład w C #:
string eol = Environment.NewLine; string lineColor = "Color: Red" + eol; string eol2 = "\n"; string lineColor2 = "Color: Blue" + eol2;
Problemy z różnymi formatami nowej liniiEdit
Plik tekstowy utworzony za pomocą gedit i wyświetlany za pomocą redaktor. Oprócz obiektów tekstowych istnieją tylko znaczniki EOL z wartością szesnastkową 0A.
Mimo że znaki sterujące są jednoznacznie zdefiniowane w odpowiedniej tabeli kodowania znaków używanej przez plik tekstowy , nadal występuje problem: istnieją różne konwencje ustawiania i wyświetlania podziału wiersza.
Aby oznaczyć pojedynczy podział wiersza, programy uniksowe używają znaku końca wiersza
, którego wartość szesnastkowa w ASCII to 0a
, podczas gdy większość programów wspólnych dla MS-DOS i Microsoft Windows używa powrót karetki
+ nowy wiersz
, którego wartość szesnastkowa w kodzie ASCII to 0d 0a . W ASCII powrót karetki jest odrębnym znakiem sterującym.
Różne konwencje nowego wiersza powodują, że pliki tekstowe, które zostały przesłane między systemami różnych typów, są wyświetlane niepoprawnie.
Tekst w tworzonych plikach z programami, które są powszechne w systemie Unix lub w klasycznym systemie Mac OS, w większości programów wspólnych dla MS-DOS i Microsoft Windows pojawiają się jako pojedyncza długa linia, ponieważ nie wyświetlają one ani jednego nowy wiersz
lub pojedynczy powrót karetki
jako znak końca wiersza.
I odwrotnie, podczas przeglądania pliku pochodzącego z komputera z systemem Windows w systemie uniksowym dodatkowa CR może być wyświetlana jako drugi podział wiersza, jako ^ M lub jako < cr > na końcu każdego wiersza.
Ponadto programy inne niż edytory tekstu mogą nie akceptować plików, np jakiś plik konfiguracyjny, zakodowany przy użyciu obcej konwencji nowego wiersza, jako prawidłowy plik.
Problem może być trudny do wykrycia, ponieważ niektóre programy poprawnie obsługują obce znaki nowej linii, a inne nie. Na przykład kompilator może zakończyć się niepowodzeniem z powodu niejasnych błędów składniowych, mimo że plik źródłowy wygląda poprawnie po wyświetleniu na konsoli lub w edytorze. W systemie uniksopodobnym polecenie cat -v mojplik.txt wyśle plik na standardowe wyjście (zwykle terminal) i uwidoczni ^ M, co może być przydatne do debugowania. Nowoczesne edytory tekstu generalnie rozpoznają wszystkie odmiany nowych linii CR + LF i pozwalają użytkownikom na konwersję między różnymi standardami. Przeglądarki internetowe są zwykle również w stanie wyświetlać pliki tekstowe i strony internetowe, które używają różnych typów znaków nowej linii.
Nawet jeśli program obsługuje różne konwencje nowego wiersza, funkcje te często nie są wystarczająco oznaczone, opisane lub udokumentowane. Zwykle menu lub pole kombi wyliczające różne konwencje nowej linii będą wyświetlane użytkownikom bez wskazania, czy zaznaczenie zostanie ponownie zinterpretowane, tymczasowo przekonwertuje lub na stałe skonwertuje znaki nowej linii. Niektóre programy niejawnie konwertują podczas otwierania, kopiowania, wklejania lub zapisywania – często niespójnie.
Większość tekstowych protokołów internetowych (w tym HTTP, SMTP, FTP, IRC i wiele innych) wymaga użycia ASCII CR + LF („\ r \ n”, 0x0D 0x0A) na poziomie protokołu, ale zalecamy, aby tolerancyjne aplikacje również rozpoznawały samotny LF („\ n”, 0x0A). Pomimo narzuconego standardu, wiele aplikacji błędnie używa sekwencji ucieczki nowej linii C „\ n” (LF) zamiast prawidłowej kombinacji sekwencji ucieczki powrotu karetki i sekwencji ucieczki nowej linii „\ r \ n” (CR + LF) (zobacz sekcję Nowa linia w języki programowania powyżej). To przypadkowe użycie niewłaściwych sekwencji ucieczki prowadzi do problemów przy próbie komunikacji z systemami stosującymi się do ściślejszej interpretacji standardów zamiast sugerowanej interpretacji tolerancyjnej. Jednym z takich nietolerancyjnych systemów jest agent transferu poczty qmail, który aktywnie odmawia przyjmowania wiadomości z systemów wysyłających czysty LF zamiast wymaganego CR + LF.
Standardowy format wiadomości internetowych dla stanów e-mail: CR i LF MUSI występują tylko razem jako CRLF; NIE MOGĄ pojawiać się niezależnie w treści.
Protokół transferu plików może automatycznie konwertować znaki nowej linii w plikach przesyłanych między systemami z różnymi reprezentacjami znaków nowej linii, gdy transfer odbywa się w „trybie ASCII”.Jednak przesyłanie plików binarnych w tym trybie zwykle ma katastrofalne skutki: każde wystąpienie sekwencji bajtów nowej linii – która nie ma semantyki terminatora linii w tym kontekście, ale jest tylko częścią normalnej sekwencji bajtów – zostanie przetłumaczone na dowolną reprezentację nowej linii inny system używa, skutecznie uszkadzając plik. Klienci FTP często stosują pewne heurystyki (na przykład inspekcję rozszerzeń plików), aby automatycznie wybierać tryb binarny lub ASCII, ale ostatecznie to użytkownicy muszą upewnić się, że ich pliki są przesyłane we właściwym trybie. Jeśli są jakiekolwiek wątpliwości co do prawidłowego trybu, należy użyć trybu binarnego, ponieważ wtedy żadne pliki nie zostaną zmienione przez FTP, chociaż mogą być wyświetlane nieprawidłowo.
Konwersja między formatami nowej liniiEdytuj
Edytory tekstu są często używane do konwersji pliku tekstowego między różnymi formatami nowej linii; Większość współczesnych edytorów potrafi czytać i zapisywać pliki używając przynajmniej różnych konwencji ASCII CR / LF.Na przykład edytor Vim może uczynić plik kompatybilnym z edytorem tekstu Windows Notepad. W ramach vim
:set fileformat=dos :wq
Edytory mogą być nieodpowiednie do konwersji większych plików lub masowej konwersji wielu plików. W przypadku większych plików (w systemie Windows NT / 2000 / XP) często używane jest następujące polecenie:
D:\>TYPE unix_file | FIND /V "" > dos_file
Programy specjalnego przeznaczenia do konwersji pliki pomiędzy różnymi konwencjami nowej linii obejmują unix2dos i dos2unix, mac2unix i unix2mac, mac2dos i dos2mac oraz flip. Polecenie tr jest dostępne w praktycznie każdym systemie uniksopodobnym i może być używane do wykonywania dowolnych operacji zastępowania pojedynczych znaków. Plik tekstowy DOS / Windows można przekonwertować na format Unix, po prostu usuwając wszystkie znaki ASCII CR za pomocą
$ tr -d "\r" < inputfile > outputfile
lub, jeśli tekst zawiera tylko znaki nowej linii CR, przez konwertowanie wszystkich znaków nowej linii CR na LF za pomocą
$ tr "\r" "\n" < inputfile > outputfile
Te same zadania są czasami wykonywane w awk, sed lub w Perlu, jeśli platforma ma interpreter Perla:
Polecenie file może identyfikować typ zakończenia linii:
$ file myfile.txt myfile.txt: ASCII English text, with CRLF line terminators
Unix egrep (rozszerzone grep) może być użyty do drukowania nazw plików z plików Unix lub DOS (zakładając tylko pliki w stylu Unix i DOS, bez Mac OS):
$ egrep -L "\r\n" myfile.txt # show UNIX style file (LF terminated)$ egrep -l "\r\n" myfile.txt # show DOS style file (CRLF terminated)
Inne narzędzia pozwalają użytkownikowi na wizualizację znaków EOL:
$ od -a myfile.txt$ cat -e myfile.txt$ hexdump -c myfile.txt