Differenza tra '\ n' e '\ r \ n'


99

Sì, sì, sono consapevole che '\n'scrive una nuova riga in UNIX, mentre per Windows v'è la sequenza di due caratteri: '\r\n'. Tutto ciò è molto bello in teoria, ma la mia domanda è: perché ? Perché il carattere di ritorno a capo è extra in Windows? Se UNIX può farlo \nperché ci vogliono due caratteri di Windows per farlo?

Sto leggendo il libro Python di David Beazley e dice:

Ad esempio, su Windows, la scrittura del carattere '\ n' genera effettivamente la sequenza di due caratteri '\ r \ n' (e durante la lettura del file, '\ r \ n' viene tradotto nuovamente in un singolo '\ n' carattere).

Perché lo sforzo extra?

Sarò onesto Conosco la differenza da molto tempo ma non mi sono mai preso la briga di chiedere PERCHÉ. Spero che abbia una risposta oggi.

Grazie per il tuo tempo.


5
Va anche notato che Windows non è l'unico che utilizza \r\n. Viene anche utilizzato dalla maggior parte dei protocolli Internet basati su testo (ad es. SMTP, HTTP, ecc.) Per lo stesso motivo di Windows (ad es. Cronologia).
Dean Harding,

3
Inoltre, quando si utilizza Java e si utilizzano stringhe di formato (ad es. System.out.printf()O String.format()), assicurarsi di utilizzarlo %ncome CRLF ai fini della compatibilità del sistema operativo. \nè deprecato.
Gary Rowe,

L'ho visto \n\rpiù volte. (Penso che sia stato qualcosa da NetWare.)
Grawity


1
Esistono pochissimi programmi Windows che richiedono effettivamente CRLF. CRLF potrebbe essere l'impostazione predefinita, ma quasi tutto si rileverà automaticamente e utilizzerà LF bene. Ho tutti i miei editor di testo su Windows configurati per usare LF per tutti i nuovi file, e non è davvero un problema.
Kevin,

Risposte:


124

Retrocompatibilità.

Windows è retrocompatibile con MS-DOS (in modo aggressivo, anche) e MS-DOS ha usato la convenzione CR-LF perché MS-DOS era compatibile con CP / M-80 (in qualche modo per caso) che ha usato la convenzione CR-LF perché era il modo in cui guidavi una stampante (perché le stampanti erano in origine macchine da scrivere controllate da computer).

Le stampanti hanno un comando separato per spostare la carta su una riga su una nuova riga e un comando separato per riportare il carrello (dove è stata montata la carta) al margine sinistro.

Ecco perchè. E sì, è un fastidio, ma fa parte del pacchetto che ha permesso a MS-DOS di vincere su CP / M e Windows 95 di vincere su tutte le altre GUI sopra a DOS e Windows XP di prendere il controllo da Windows 98.

(Nota: le moderne stampanti laser hanno ancora questi comandi perché anche loro sono retrocompatibili con le stampanti precedenti, in particolare HP lo fa bene)

Per coloro che non hanno familiarità con le macchine da scrivere, ecco un video che mostra come è stata digitata: http://www.youtube.com/watch?v=LJvGiU_UyEQ . Si noti che la carta viene prima spostata verso l'alto e quindi il carrello viene restituito, anche se accade con un semplice movimento. Il ding notificò alla dattilografa che la fine era vicina e si preparò.


3
In che modo Unix con il suo \ n funzionava solo con la vecchia stampante? Suppongo che le console Unix fossero collegate alle stampanti per macchine da scrivere?
Senthil Kumaran,

3
@Senthil, in Unix il carattere di nuova riga viene convertito dal driver finale. È solo una decisione di progettazione diversa.

2
@Senthil, per essere precisi, nelle stampanti e nei terminali Unix sono astratte nel sistema operativo e la loro descrizione determina quali sequenze di byte vengono generate per il dispositivo. CP / M non ha avuto tale astrazione lasciando tutto al programma in esecuzione - questo è molto probabilmente perché non era necessario per tutti i programmi, quindi averlo nel sistema operativo residente avrebbe portato via memoria preziosa dai programmi che non ne avevano bisogno. Ricorda che CP / M è stato progettato per un sistema da 16 Kilobyte .

1
"Quindi una delle principali caratteristiche progettuali di quello che è probabilmente il sistema di trasporto più avanzato del mondo è stata originariamente determinata dalla larghezza del culo di un cavallo." E così è anche con il software. astrodigital.org/space/stshorse.html
Ryan Michela,

1
@Ryan, leggenda urbana. Debunked su snopes.com/history/american/gauge.htm

20

Per quanto ne so, questo risale ai tempi delle macchine da scrivere.

\r è il ritorno a capo, che è ciò che si sposta nel punto in cui si sta digitando sulla pagina a sinistra (o a destra se questa è la propria cultura)

\n è una nuova riga, che sposta la carta su una riga.

Fare solo uno di questi su una macchina da scrivere ti metterebbe nel posto sbagliato per iniziare a scrivere una nuova riga di testo.

Quando sono arrivati ​​i computer, immagino che alcune persone abbiano mantenuto il vecchio modello, ma altri hanno capito che non era necessario e hanno incapsulato una nuova linea come un personaggio.


7
Quindi perché Windows si attacca ancora ?
sukhbir,

8
Retrocompatibilità. Immagina quanti documenti di testo si spezzerebbero se cambiassero ora
Matt Ellen,

4
A rigor di termini, la "strana palla" qui è l'ixoid 'usa solo la nuova riga', inizialmente fatto (credo) per mantenere basso il numero di caratteri memorizzati (la traduzione in CR LF è fatta nel driver del terminale, è la bandiera 'onlcr' che lo controlla per l'output.
Vatine

3
Windows aveva un predecessore di nome DOS, che aveva lo stesso finale di riga. Windows ha mantenuto la compatibilità. DOS aveva predecessori stessi, vale a dire CP / M. Quello ha usato anche CRLF. DOS ha mantenuto la compatibilità. Lo sviluppo di CP / M è stato influenzato da TOP TOP DEC. E puoi indovinare, quale allineamento hanno usato. :-) La compatibilità spiega molto.
Mnementh

5
OK, ma perché Blocco note non riconosce ancora le terminazioni di riga "\ n"?
dan04,

8

Non so se questa è una conoscenza comune, ma va notato che CR è ancora compreso dai moderni emulatori di terminali:

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

È utile per gli indicatori di progresso, ad es

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

1
Sulle vecchie stampanti di linea IBM (ad esempio, il 1403), la convenzione prevedeva di trattare il primo carattere del buffer di linea come un carattere di controllo del carrello. Vuoto significava avanzare di una riga e stampare. Plus intendeva omettere la spaziatura e veniva utilizzato, ad esempio, per sottolineare. Uno zero significava doppio spazio e meno a triplo spazio. Un '1' distanziato all'inizio della pagina successiva e altre cifre avanzano a posizioni verticali definite dall'utente (utilizzate per compilare moduli prestampati).
George

7

Storicamente, l'avanzamento di riga significava che il rullo - il rullo su cui si digita - ruotava di una riga, facendo apparire il testo sulla riga successiva ... ma nella colonna successiva.

Carriage return significa "restituisce il bit con cui si digita all'inizio della riga".

Windows utilizza CR + LF perché MS-DOS lo faceva, perché CP / M lo faceva, perché aveva senso per le linee seriali.

Unix ha copiato la sua convenzione \ n perché Multics ha fatto.

Ho il sospetto che se scavi abbastanza indietro, troverai un disaccordo politico tra gli implementatori!

(Hai lasciato fuori il bit extra divertente, in cui la convenzione Mac è (o era una volta) per usare solo CR per separare le linee. E ora Unicode ha anche un proprio separatore di linee, U + 2028!)


Wow! non sapevo del Mac ...
Michael K il

Non sono sicuro che troverai un disaccordo politico. È anche possibile trovare persone che fanno cose simili in modo indipendente.
David Thornley,

1
Quando sono coinvolti organismi di standard diversi? Sarei sorpreso di non trovare ragioni politiche!
Frank Shearar,

6

Storia del personaggio di Newline (Wikipedia):

ASCII è stato sviluppato contemporaneamente da ISO e ASA, l'organizzazione precedente a ANSI. Durante il periodo 1963-1968, i progetti di standard ISO supportarono l'uso di CR + LF o LF da solo come una nuova linea, mentre i progetti ASA supportarono solo CR + LF.

La sequenza CR + LF era di uso comune su molti primi sistemi di computer che avevano adottato macchine teletype, in genere un ASR33, come dispositivo console, poiché questa sequenza era necessaria per posizionare tali stampanti all'inizio di una nuova linea. Su questi sistemi, il testo era spesso composto abitualmente per essere compatibile con queste stampanti, poiché il concetto di driver di dispositivo che nascondeva tali dettagli hardware dall'applicazione non era ancora ben sviluppato; le applicazioni dovevano parlare direttamente con la macchina del teletipo e seguire le sue convenzioni.

La separazione delle due funzioni nascondeva il fatto che la testina di stampa non poteva tornare dall'estrema destra all'inizio della riga successiva in un tempo di un carattere. Questo è il motivo per cui la sequenza è sempre stata inviata per prima con il CR. In effetti, spesso era necessario inviare caratteri extra (CR o NUL estranei, che vengono ignorati) per dare alla testina di stampa il tempo di spostarsi sul margine sinistro.

Anche dopo che i teletipi sono stati sostituiti da terminali di computer con baud rate più elevati, molti sistemi operativi supportano comunque l'invio automatico di questi caratteri di riempimento, per la compatibilità con terminali più economici che richiedono tempi di caratteri multipli per scorrere il display.

MS-DOS (1981) ha adottato CR + LF di CP / M; L'uso di CR + LF da parte di CP / M aveva senso per l'utilizzo di terminali di computer tramite linee seriali. Questa convenzione è stata ereditata dal successivo sistema operativo Windows di Microsoft.

Il sistema operativo Multics iniziò lo sviluppo nel 1964 e utilizzò LF da solo come nuova linea. Unix seguì la pratica del Multics e successivamente i sistemi seguirono Unix.


Sul vecchio terminale della tastiera della stampante IBM 2741, il componente della stampante era una macchina da scrivere a sfera di tipo rimbalzante IBM Selectric. Il cambio in maiuscolo faceva ruotare la palla, impiegando più tempo. Nel codice di carattere EBCDIC, i caratteri maiuscoli avevano 1 bit in posizione 6. Quindi, uno spazio vuoto EBCDIC (0x40) era maiuscolo! Se stavi stampando un lungo documento (ad es. Una tesi), potresti accelerare materialmente l'output traducendo spazi vuoti tra parole minuscole in NUL o spazi vuoti minuscoli (hanno usato un carattere diverso, IL se la memoria serve, per introdurre i ritardi necessari, ad es. , al ritorno o alla tabulazione).
George

5

Cosa succede quando le persone chiedono "perché Unix può fare \ne non Windows"? È una domanda così strana.

  1. Il sistema operativo non ha quasi nulla a che fare con esso. È più una questione di come app, librerie, protocolli e formati di file gestiscono le cose. A parte il caso in cui il sistema operativo legge / scrive i comandi della riga di comando o di configurazione basati su testo, non ha senso criticare il sistema operativo.
  2. La maggior parte delle applicazioni Windows possono leggere sia \ne \r\nbene. Hanno anche prodotto in \r\nmodo che tutti siano felici. Un programma non "fa" semplicemente \no \r\n- accetta uno, l'altro o entrambi, e genera uno, l'altro o entrambi.
  3. Come programmatore, questo non dovrebbe quasi mai disturbarti. Praticamente ogni lingua / piattaforma dispone di strutture per scrivere la riga finale corretta e leggere in modo più efficace. L'unica volta che ho avuto a che fare con il problema è stato quando ho scritto un server HTTP - ed è stato perché un certo browser (suggerimento: il browser più popolare dopo IE) stava facendo \ninvece il corretto \r\n .
  4. Una domanda molto più pertinente è: perché così tante app Unix moderne escono solo \nsapendo pienamente che ci sono alcuni protocolli e programmi a cui non piace?

3
Un'altra domanda pertinente: poiché molti protocolli sono stati sviluppati principalmente su sistemi Unix, perché non hanno usato '\ n'?
David Thornley,

@DavidThornley Perché \ r \ n è più probabile che funzioni multipiattaforma (\ r per mac più vecchi, \ r \ n per windows e \ n per * nix).
Base

4

Il motivo per cui le convenzioni si basano sui loro vari sistemi (\ n su sistemi di tipo unix, \ r \ n su Windows, ecc.) È che una volta scelta una convenzione NON PUOI cambiarla senza rompere un mucchio di file di persone. E questo è generalmente malvisto.

I sistemi di tipo Unix furono sviluppati (molto presto) usando vari modelli di teletipo, e ad un certo punto qualcuno decise che l'attrezzatura avrebbe dovuto tornare al carrello quando faceva un avanzamento di linea.

Windows proveniva da DOS, quindi per Windows la domanda è davvero: perché DOS ha usato questa sequenza cr / lf? Immagino che abbia qualcosa a che fare con CP / M, dove DOS ha alcune delle sue radici. Ancora una volta, modelli specifici di teletipo potrebbero aver avuto un ruolo.


Hmm interessante.
sukhbir,

1
Perché Windows non è in grado di gestire le linee che terminano con \n, ma \r\nper ora continuano a utilizzare ? Se lo facessero a partire da Windows XP, ora potrebbero iniziare a salvare i file \ninvece di \r\n.
DisgruntledGoat

1
Windows non ha nulla a che fare con esso. È la decisione delle app e la maggior parte delle app leggerà sia '\ n' che '\ r \ n' e scriverà '\ r \ n', quindi tutti sono felici.
Rei Miyasaka,

2

Ecco una risposta dalla migliore fonte: Microsoft. Perché il terminatore di linea CR + LF?

Questo protocollo risale ai tempi dei teletypewriter. CR sta per "ritorno a capo" - il carattere di controllo CR ha riportato la testina di stampa ("carrello") alla colonna 0 senza far avanzare la carta. LF sta per "avanzamento riga": il carattere di controllo LF fa avanzare la carta di una riga senza muovere la testina di stampa. Quindi, se si desidera riportare la testina di stampa nella colonna zero (pronta per stampare la riga successiva) e far avanzare la carta (in modo che stampi su carta nuova), è necessario sia CR che LF.

Se vai ai vari documenti del protocollo Internet, come RFC 0821 (SMTP), RFC 1939 (POP), RFC 2060 (IMAP) o RFC 2616 (HTTP), vedrai che tutti specificano CR + LF come sequenza di terminazione della linea. Quindi la vera domanda non è "Perché CP / M, MS-DOS e Win32 usano CR + LF come terminatore di linea?" ma piuttosto "Perché altre persone hanno scelto di differire da questi documenti standard e di usare un altro terminatore di linea?"

Unix ha adottato LF semplice come sequenza di terminazione di linea. Se guardi le opzioni stty, vedrai che l'opzione onlcr specifica se un LF deve essere cambiato in CR + LF. Se si sbaglia questa impostazione, si ottiene il testo di scale, dove

each
    line
        begins

dove la riga precedente era stata interrotta. Quindi anche unix, se lasciato in modalità raw, richiede CR + LF per terminare le linee. Il CR implicito prima di LF è un'invenzione unix, probabilmente come economia, poiché consente di risparmiare un byte per riga.

L'antenato unix del linguaggio C portava questa convenzione nello standard del linguaggio C, che richiede solo "\ n" (che codifica LF) per terminare le linee, ponendo l'onere sulle librerie di runtime per convertire i dati di file grezzi in linee logiche.

Il linguaggio C ha anche introdotto il termine "newline" per esprimere il concetto di "terminatore di linea generico". Mi è stato detto che il comitato ASCII ha cambiato il nome del personaggio 0x0A in "newline" intorno al 1996, quindi il livello di confusione è stato aumentato ancora di più.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.