it-swarm.it

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

Sì sì, sono consapevole che '\n' scrive una nuova riga in UNIX mentre per Windows esiste la sequenza di due caratteri: '\r\n'. Tutto questo è molto bello in teoria, ma la mia domanda è why ? Perché il carattere di ritorno a capo è extra in Windows? Se UNIX può farlo in \n perché 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.

108
sukhbir

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 per sostituire 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 chi non ha familiarità con le macchine da scrivere, ecco un video che mostra come è stata eseguita la digitazione: 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ò.

133
user1249

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 stai digitando sulla pagina a sinistra (o a destra se questa è la tua 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.

21
Matt Ellen

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
9
Daniel Lubarov

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 usa CR + LF perché lo faceva MS-DOS, 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 attuatori!

(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!)

7
Frank Shearar

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 riga, mentre le bozze ASA supportavano 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 regolarmente 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 prima con 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 sistema operativo Windows successivo di Microsoft.

Il sistema operativo Multics iniziò lo sviluppo nel 1964 e usò LF da solo come newline. Unix seguì la pratica Multics, e successivamente i sistemi seguirono Unix.

6
Craige

Cosa succede quando le persone chiedono "perché Unix può fare \n e 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 app di Windows può leggere sia \n e \r\n va bene. Hanno anche prodotto \r\n in modo che tutti siano felici. Un programma non semplicemente "fa" né \n o \r\n - esso accetta uno, l'altro o entrambi, e output uno, l'altro o entrambi.
  3. Come programmatore, questo non dovrebbe quasi mai non 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 dovuto affrontare il problema è stato quando ho scritto un server HTTP - ed è stato perché un certo browser (suggerimento: il browser più popolare dopo IE) stava facendo \n anziché il corretto\r\n.
  4. Una domanda molto più pertinente è: perché così tante app Unix moderne producono solo \n sapendo pienamente che ci sono alcuni protocolli e programmi a cui non piace?
5
Rei Miyasaka

Il motivo per cui le convenzioni si aggrappano ai 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 le attrezzature avrebbero dovuto tornare al carrello quando ha fatto 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.

4
Michael Kohne

Ecco una risposta dalla migliore fonte: Microsoft. Perché il terminatore di riga 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 ha avanzato la carta di una riga senza spostare la testina di stampa. Quindi, se si desidera riportare la testina di stampa in colonna zero (pronto per stampare la riga successiva) e far avanzare la carta (in modo che stampi su carta nuova), sono necessari 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 plain LF come sequenza di terminazione della linea. Se guardi le opzioni stty, vedrai che l'opzione onlcr specifica se a LF dovrebbe essere modificato 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 ASCII ha cambiato il nome del personaggio 0x0A in "newline" intorno al 1996, quindi il livello di confusione è stato aumentato ancora di più.

2
Ondra Žižka