Nuova riga
I concetti di ritorno a capo (CR) e avanzamento riga (LF) sono strettamente associati e possono essere considerati separatamente o insieme. Nel supporto fisico di macchine da scrivere e stampanti, sono necessari due assi di movimento, “verso il basso” e “trasversalmente”, per creare una nuova linea sulla pagina. Sebbene il progetto di una macchina (macchina da scrivere o stampante) debba considerarli separatamente, la logica astratta del software può combinarli insieme come un unico evento. Questo è il motivo per cui una nuova riga nella codifica dei caratteri può essere definita come CR
e LF
combinati in uno (comunemente chiamato CR + LF
o CRLF
).
Alcuni i set di caratteri forniscono un codice di carattere di nuova riga separato. EBCDIC, ad esempio, fornisce un codice di caratteri NL oltre ai codici CR e LF. Unicode, oltre a fornire i codici di controllo ASCII CR e LF, fornisce anche un codice di controllo “riga successiva” (NEL), nonché codici di controllo per indicatori di “separatore di riga” e “separatore di paragrafo”.
- Sistemi EBCDIC, principalmente sistemi mainframe IBM, inclusi z / OS (OS / 390) e i5 / OS (OS / 400), utilizzano NL (New Line, 0x15) come carattere che combina le funzioni di avanzamento riga e carrello ritorno. Il carattere Unicode equivalente (
0x85
) è chiamato NEL (riga successiva). EBCDIC ha anche caratteri di controllo chiamati CR e LF, ma il valore numerico di LF (0x25) è diverso da quello usato da ASCII (0x0A). Inoltre, alcune varianti EBCDIC utilizzano anche NL ma assegnano un codice numerico diverso al carattere. Tuttavia, questi sistemi operativi utilizzano un file system basato sui record, che memorizza i file di testo come un record per riga. Nella maggior parte dei formati di file, nessun terminatore di riga viene effettivamente memorizzato. - I sistemi operativi per la serie CDC 6000 definivano una nuova riga come due o più caratteri a sei bit con valore zero alla fine di una parola a 60 bit. Alcune configurazioni definivano anche un carattere a valore zero come carattere di due punti, con il risultato che più due punti potevano essere interpretati come una nuova riga a seconda della posizione.
- RSX-11 e OpenVMS utilizzano anche un file system basato su record , che memorizza i file di testo come un record per riga. Nella maggior parte dei formati di file, nessun terminatore di riga viene effettivamente memorizzato, ma la funzione Record Management Services può aggiungere in modo trasparente un terminatore a ciascuna riga quando viene recuperato da un’applicazione. I record stessi potrebbero contenere gli stessi caratteri di terminazione di riga, che potrebbero essere considerati una funzionalità o un fastidio a seconda dell’applicazione. RMS non solo memorizzava i record, ma memorizzava anche metadati sui separatori di record in bit diversi affinché il file complicasse ulteriormente le cose (poiché i file potevano avere record di lunghezza fissa, record che erano preceduti da un conteggio o record terminati da un carattere specifico ). I bit non erano “generici, quindi mentre potevano specificare che CRLF o LF o anche CR era il terminatore di riga, non potevano sostituire un altro codice.
- La lunghezza della linea fissa veniva utilizzata da alcuni dei primi mainframe operativi sistemi. In un tale sistema, ad esempio, si presumeva una fine riga implicita ogni 72 o 80 caratteri. Nessun carattere di nuova riga è stato memorizzato. Se un file veniva importato dal mondo esterno, le linee più corte della lunghezza della linea dovevano essere riempite con spazi, mentre le linee più lunghe della lunghezza della linea dovevano essere troncate. Questo imitava l’uso di schede perforate, su cui ogni riga era memorizzata su una scheda separata, di solito con 80 colonne su ciascuna scheda, spesso con numeri di sequenza nelle colonne 73-80. Molti di questi sistemi hanno aggiunto un carattere di controllo del carrello all’inizio del record successivo; questo potrebbe indicare se il record successivo era una continuazione della riga iniziata dal record precedente, o una nuova riga, o dovrebbe sovrastampare la riga precedente (simile a una CR). Spesso si trattava di un normale carattere di stampa come
#
che quindi non poteva essere utilizzato come primo carattere di una riga. Alcune delle prime stampanti di riga interpretavano questi caratteri direttamente nei record loro inviati.
UnicodeEdit
Lo standard Unicode definisce un numero di caratteri che le applicazioni conformi dovrebbero riconoscere come terminatori di riga:
LF: Line Feed, U + 000A VT: tabulazione verticale, U + 000B FF: avanzamento modulo, U + 000C CR: ritorno a capo, U + 000D CR + LF: CR (U + 000D) seguito da LF (U + 000A) NEL: riga successiva, U + 0085 LS: Separatore di riga, U + 2028 PS: Separatore di paragrafo, U + 2029
Questo può sembrare eccessivamente complicato rispetto a un approccio come la conversione di tutti i terminatori di riga in un singolo carattere, ad esempio LF. Tuttavia, Unicode è stato progettato per preservare tutte le informazioni durante la conversione di un file di testo da qualsiasi codifica esistente in Unicode e viceversa. Pertanto, Unicode dovrebbe contenere caratteri inclusi nelle codifiche esistenti.NL è incluso in EBCDIC con codice 0x15 e spesso mappato a NEL, che è un carattere di controllo nel set di controlli C1. In quanto tale, è definito da ECMA 48 e riconosciuto da codifiche conformi a ISO / IEC 2022 (che è equivalente a ECMA 35). Il set di controllo C1 è anche compatibile con ISO-8859-1. L’approccio adottato nello standard Unicode consente la trasformazione di andata e ritorno per preservare le informazioni pur consentendo alle applicazioni di riconoscere tutti i possibili tipi di terminatori di riga.
Riconoscendo e utilizzando i codici di nuova riga maggiori di 0x7F (NEL, LS e PS) non viene fatto spesso. Sono più byte in UTF-8 e il codice per NEL è stato utilizzato come carattere di puntini di sospensione (…
) in Windows-1252. Ad esempio:
- ECMAScript accetta LS e PS come interruzioni di riga, ma considera gli spazi bianchi U + 0085 (NEL) invece di un’interruzione di riga.
- Windows 10 non tratta nessuna delle voci NEL, LS o PS come interruzioni di riga nel suo editor di testo predefinito, Blocco note.
- gedit, l’editor di testo predefinito dell’ambiente desktop GNOME , tratta LS e PS come newline ma non per NEL.
- JSON consente caratteri LS e PS all’interno di stringhe, mentre ECMAScript prima di ES2019 li trattava come newline e quindi sintassi illegale.
- YAML non li riconosce più come speciali a partire dalla versione 1.2, per essere compatibili con JSON.
I caratteri Unicode U + 2424 (SIMBOLO PER NEWLINE, 
), U + 23CE (RETURN SYMBOL, ⏎
), U + 240D (SIMBOLO PER CARRIAGE RETURN, ␍
) e U + 240A (SIMBOLO PER ALIMENTAZIONE LINEA, ␊
) sono destinati a presentare un carattere visibile all’utente al lettore del documento e quindi non vengono riconosciuti come una nuova riga.
Sequenze di escape Modifica
Una sequenza di escape è una combinazione di caratteri che non rappresenta alcun testo; invece di essere visualizzato (come testo) dovrebbe essere intercettato dal programma e dovrebbe essere eseguita una funzione speciale. Le sequenze di escape vengono anche utilizzate per gestire (impostare, cercare, sostituire, ecc.) Caratteri speciali.
Nei linguaggi di programmazione Modifica
Per facilitare la creazione di programmi portabili, i linguaggi di programmazione forniscono alcune astrazioni per gestire i diversi tipi di sequenze di nuova riga usate in ambienti diversi.
Il linguaggio di programmazione C fornisce le sequenze di escape “\ n” (nuova riga) e “\ r” (ritorno a capo). Tuttavia, non è necessario che questi siano equivalenti ai caratteri di controllo ASCII LF e CR. Lo standard C garantisce solo due cose:
- Ciascuna di queste sequenze di escape è mappata a un numero univoco definito dall’implementazione che può essere memorizzato in un singolo valore di carattere.
- Durante la scrittura in un file, nodo di dispositivo o socket / fifo in modalità testo, “\ n” viene tradotto in modo trasparente nella sequenza di nuova riga nativa usata dal sistema, che può essere più lunga di un carattere. Durante la lettura in modalità testo, la sequenza nativa di nuova riga viene tradotta in “\ n”. In modalità binaria, non viene eseguita alcuna traduzione e la rappresentazione interna prodotta da “\ n” viene emessa direttamente.
Sulle piattaforme Unix, dove ha avuto origine il C, la sequenza nativa di nuova riga è ASCII LF ( 0x0A), quindi “\ n” è stato semplicemente definito come quel valore. Poiché la rappresentazione interna ed esterna sono identiche, la traduzione eseguita in modalità testo è un no-op e Unix non ha la nozione di modalità testo o modalità binaria. Ciò ha indotto molti programmatori che hanno sviluppato il loro software su sistemi Unix semplicemente ignorare completamente la distinzione, risultando in codice che non è portabile su piattaforme diverse.
La funzione di libreria C fgets () è meglio evitare in modalità binaria perché qualsiasi file non scritto con la convenzione di nuova riga di Unix verrà letto male. Inoltre, in modalità testo, anche qualsiasi file non scritto con la sequenza di nuova riga nativa del sistema (come un file creato su un sistema Unix, quindi copiato su un sistema Windows) verrà letto male.
Un altro problema comune è l’uso di “\ n” quando si comunica utilizzando un protocollo Internet che impone l’uso di ASCII CR + LF per le righe finali. Scrivere “\ n” in un flusso in modalità testo funziona correttamente sui sistemi Windows, ma produce solo LF su Unix, e qualcosa di completamente diverso su sistemi più esotici. Usare “\ r \ n” in modalità binaria è leggermente migliore.
Le librerie Java I / O non le traducono in modo trasparente in sequenze di nuova riga dipendenti dalla piattaforma su input o output. Invece, forniscono funzioni per scrivere una riga intera che aggiunge automaticamente la sequenza nativa di nuova riga e funzioni per leggere righe che accettano qualsiasi CR, LF o CR + LF come terminatore di riga (vedere BufferedReader.readLine () Il metodo System.lineSeparator () può essere utilizzato per recuperare il separatore di riga sottostante.
Esempio:
String eol = System.lineSeparator(); String lineColor = "Color: Red" + eol;
Python consente “Universal Newline Support” quando si apre un file per la lettura, quando durante l’importazione di moduli e durante l’esecuzione di un file.
Alcuni linguaggi hanno creato variabili, costanti e subroutine speciali per facilitare il ritorno a capo durante l’esecuzione del programma. In alcuni linguaggi come PHP e Perl, le virgolette doppie sono necessarie per eseguire la sostituzione di escape per tutte le sequenze di escape, inclusi “\ n” e “\ r”. In PHP, per evitare problemi di portabilità, le sequenze di nuova riga dovrebbero essere emesse utilizzando la costante PHP_EOL.
Esempio in C #:
string eol = Environment.NewLine; string lineColor = "Color: Red" + eol; string eol2 = "\n"; string lineColor2 = "Color: Blue" + eol2;
Problemi con diversi formati di nuova riga Modifica
Un file di testo creato con gedit e visualizzato con un esadecimale editore. Oltre agli oggetti di testo, ci sono solo marcatori EOL con il valore esadecimale 0A.
Anche se i caratteri di controllo sono definiti in modo inequivocabile nella corrispondente tabella di codifica dei caratteri usata da un file di testo , c’è ancora un problema: ci sono diverse convenzioni per impostare e visualizzare un’interruzione di riga.
Per denotare una singola interruzione di riga, i programmi Unix usano avanzamento riga
, il cui valore esadecimale in ASCII è 0a
, mentre la maggior parte dei programmi comuni a MS-DOS e Microsoft Windows utilizza ritorno a capo
+ avanzamento riga
, il cui valore esadecimale in ASCII è 0d 0a . In ASCII, il ritorno a capo è un carattere di controllo distinto.
Le diverse convenzioni di nuova riga fanno sì che i file di testo che sono stati trasferiti tra sistemi di diversi tipi vengano visualizzati in modo errato.
Testo nei file creati con i programmi comuni su Mac OS tipo Unix o classico, appaiono come un’unica lunga riga sulla maggior parte dei programmi comuni a MS-DOS e Microsoft Windows perché questi non visualizzano un singolo avanzamento riga
o un singolo ritorno a capo
come interruzione di riga.
Al contrario, quando si visualizza un file proveniente da un computer Windows su un sistema simile a Unix, la risposta predefinita aggiuntiva può essere visualizzata come seconda interruzione di riga, come ^ M o come < cr > alla fine di ogni riga.
Inoltre, programmi diversi dagli editor di testo potrebbero non accettare un file, ad es qualche file di configurazione, codificato usando la convenzione di newline straniera, come file valido.
Il problema può essere difficile da individuare perché alcuni programmi gestiscono correttamente i newline stranieri mentre altri no. Ad esempio, un compilatore potrebbe non riuscire con oscuri errori di sintassi anche se il file di origine sembra corretto quando viene visualizzato sulla console o in un editor. Su un sistema Unix-like, il comando cat -v myfile.txt invierà il file a stdout (normalmente il terminale) e renderà visibile ^ M, che può essere utile per il debug. I moderni editor di testo generalmente riconoscono tutti i tipi di newline CR + LF e consentono agli utenti di convertire tra i diversi standard. I browser Web di solito sono anche in grado di visualizzare file di testo e siti Web che utilizzano diversi tipi di nuova riga.
Anche se un programma supporta diverse convenzioni di nuova riga, queste funzionalità spesso non sono sufficientemente etichettate, descritte o documentate. In genere un menu o una casella combinata che enumera diverse convenzioni di nuova riga verrà visualizzato agli utenti senza un’indicazione se la selezione reinterpreterà, convertirà temporaneamente o convertirà permanentemente le nuove righe. Alcuni programmi convertiranno implicitamente all’apertura, copia, incolla o salvataggio, spesso in modo incoerente.
La maggior parte dei protocolli Internet testuali (inclusi HTTP, SMTP, FTP, IRC e molti altri) impongono l’uso di ASCII CR + LF (“\ r \ n”, 0x0D 0x0A) a livello di protocollo, ma consigliamo alle applicazioni tolleranti di riconoscere anche LF solitario (“\ n”, 0x0A). Nonostante lo standard dettato, molte applicazioni utilizzano erroneamente la sequenza di escape di nuova riga C “\ n” (LF) invece della corretta combinazione di sequenze di escape di ritorno a capo e di escape di nuova riga “\ r \ n” (CR + LF) (vedere la sezione Newline in linguaggi di programmazione sopra). Questo uso accidentale di sequenze di fuga sbagliate porta a problemi quando si cerca di comunicare con sistemi che aderiscono all’interpretazione più rigorosa degli standard invece dell’interpretazione tollerante suggerita. Uno di questi sistemi intolleranti è l’agente di trasferimento della posta di qmail che rifiuta attivamente di accettare messaggi da sistemi che inviano LF nudo invece del CR + LF richiesto.
Il formato dei messaggi Internet standard per la posta elettronica afferma: CR e LF DEVONO si verificano solo insieme come CRLF; NON DEVONO apparire indipendentemente nel corpo.
Il File Transfer Protocol può convertire automaticamente i newline in file trasferiti tra sistemi con differenti rappresentazioni di newline quando il trasferimento è fatto in “modalità ASCII”.Tuttavia, il trasferimento di file binari in questa modalità di solito ha risultati disastrosi: qualsiasi occorrenza della sequenza di byte di nuova riga, che non ha la semantica del terminatore di riga in questo contesto, ma è solo una parte di una normale sequenza di byte, verrà tradotta in qualsiasi rappresentazione di nuova riga l’altro sistema utilizza, corrompendo efficacemente il file. I client FTP spesso utilizzano alcune euristiche (ad esempio, l’ispezione delle estensioni dei nomi di file) per selezionare automaticamente la modalità binaria o ASCII, ma alla fine spetta agli utenti assicurarsi che i propri file vengano trasferiti nella modalità corretta. In caso di dubbi sulla modalità corretta, è necessario utilizzare la modalità binaria, poiché in tal caso nessun file verrà alterato dall’FTP, anche se potrebbe essere visualizzato in modo errato.
Conversione tra formati di nuova riga Modifica
Gli editor di testo vengono spesso utilizzati per convertire un file di testo tra diversi formati di nuova riga; i più moderni editor possono leggere e scrivere file usando almeno le diverse convenzioni ASCII CR / LF. Ad esempio, l’editor Vim può rendere un file compatibile con l’editor di testo Blocco note di Windows. All’interno di vim
:set fileformat=dos :wq
Gli editor possono non essere adatti alla conversione di file più grandi o alla conversione di massa di molti file. Per file più grandi (su Windows NT / 2000 / XP) viene spesso utilizzato il seguente comando:
D:\>TYPE unix_file | FIND /V "" > dos_file
Programmi speciali da convertire file tra diverse convenzioni di nuova riga includono unix2dos e dos2unix, mac2unix e unix2mac, mac2dos e dos2mac e flip. Il comando tr è disponibile praticamente su tutti i sistemi Unix e può essere utilizzato per eseguire operazioni di sostituzione arbitrarie su singoli caratteri. Un file di testo DOS / Windows può essere convertito in formato Unix semplicemente rimuovendo tutti i caratteri ASCII CR con
$ tr -d "\r" < inputfile > outputfile
o, se il testo ha solo nuove righe CR, con conversione di tutte le nuove righe CR in LF con
$ tr "\r" "\n" < inputfile > outputfile
Le stesse attività a volte vengono eseguite con awk, sed o in Perl se la piattaforma ha un interprete Perl:
Il comando file può identificare il tipo di fine riga:
$ file myfile.txt myfile.txt: ASCII English text, with CRLF line terminators
Il comando Unix egrep (extended grep) può essere usato per stampare nomi di file di file Unix o DOS (assumendo solo file in stile Unix e DOS, no 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)
Altri strumenti consentono all’utente di visualizzare i caratteri EOL:
$ od -a myfile.txt$ cat -e myfile.txt$ hexdump -c myfile.txt