Diferencia entre '\ n' y '\ r \ n'

99

Sí sí, soy consciente de que '\n'escribe una nueva línea en UNIX, mientras que para Windows se encuentra la secuencia de dos caracteres: '\r\n'. Todo esto es muy bueno en teoría, pero mi pregunta es ¿por qué ? ¿Por qué el carácter de retorno de carro es adicional en Windows? Si UNIX puede hacerlo, \n¿ por qué se necesitan dos caracteres de Windows para hacer esto?

Estoy leyendo el libro de Python de David Beazley y él dice:

Por ejemplo, en Windows, escribir el carácter '\ n' en realidad genera la secuencia de dos caracteres '\ r \ n' (y al leer el archivo nuevamente, '\ r \ n' se traduce nuevamente en un solo '\ n' personaje).

¿Por qué el esfuerzo extra?

Voy a ser sincero. He sabido la diferencia por mucho tiempo pero nunca me he molestado en preguntar POR QUÉ. Espero que se responda hoy.

Gracias por tu tiempo.

sukhbir
fuente
55
También debe tenerse en cuenta que Windows no es el único que usa \r\n. También es utilizado por la mayoría de los protocolos de Internet basados ​​en texto (por ejemplo, SMTP, HTTP, etc.) por la misma razón que Windows (es decir, el historial).
Dean Harding
3
Además, cuando esté en Java y use cadenas de formato (por ejemplo, System.out.printf()o String.format()) asegúrese de usarlo %ncomo su CRLF para fines de compatibilidad con el sistema operativo. \nes obsoleto.
Gary Rowe
Lo he visto \n\rvarias veces. (Creo que fue algo de NetWare)
Grawity
1
Hay muy pocos programas de Windows que realmente requieren CRLF. CRLF puede ser el valor predeterminado, pero casi todo se detectará automáticamente y usará LF perfectamente. Tengo todos mis editores de texto en Windows configurados para usar LF para todos los archivos nuevos, y realmente no es un problema.
Kevin

Respuestas:

124

Compatibilidad con versiones anteriores.

Windows es retrocompatible con MS-DOS (agresivamente, incluso) y MS-DOS usó la convención CR-LF porque MS-DOS era compatible con CP / M-80 (algo por accidente) que usaba la convención CR-LF porque eso fue cómo manejaste una impresora (porque las impresoras eran originalmente máquinas de escribir controladas por computadora).

Las impresoras tienen un comando separado para mover el papel una línea hacia arriba a una nueva línea, y un comando separado para devolver el carro (donde estaba montado el papel) de regreso al margen izquierdo.

Es por eso. Y sí, es una molestia, pero es parte del paquete que permitió que MS-DOS ganara a CP / M, y Windows 95 ganara a todas las otras GUI sobre DOS, y Windows XP a hacerse cargo. de Windows 98.

(Nota: las impresoras láser modernas todavía tienen estos comandos porque también son compatibles con versiones anteriores de impresoras anteriores, HP en particular lo hace bien)

Para aquellos que no están familiarizados con las máquinas de escribir, aquí hay un video que muestra cómo se escribió: http://www.youtube.com/watch?v=LJvGiU_UyEQ . Observe que el papel primero se mueve hacia arriba y luego se devuelve el carro, incluso si ocurre en un movimiento simple. El ding notificó al mecanógrafo que el final estaba cerca y que se preparara para ello.


fuente
3
¿Cómo funcionaba Unix con su \ n solía funcionar con los viejos tiempos de la impresora? ¿Supongo que tenían consolas Unix conectadas a impresoras tipo máquina de escribir?
Senthil Kumaran
3
@Senthil, en Unix el carácter de nueva línea es convertido por el controlador final. Es solo una decisión de diseño diferente.
2
@Senthil, para ser precisos, en las impresoras y terminales Unix se abstraen en el sistema operativo, y su descripción determina qué secuencias de bytes se generan para el dispositivo. CP / M no tenía tal abstracción dejándolo todo al programa en ejecución; esto es muy probable porque no era necesario para todos los programas, por lo que tenerlo en el sistema operativo residente quitaría una memoria preciosa de los programas que no lo necesitan. Recuerde que CP / M fue diseñado para un sistema de 16 kilobytes .
1
"Entonces, una característica importante del diseño de lo que podría decirse que es el sistema de transporte más avanzado del mundo fue determinada originalmente por el ancho del culo de un caballo". Y lo mismo ocurre con el software también. astrodigital.org/space/stshorse.html
Ryan Michela
1
@ Ryan, leyenda urbana. Debunked en snopes.com/history/american/gauge.htm
20

Hasta donde sé, esto se remonta a los días de las máquinas de escribir.

\r es el retorno de carro, que es lo que se mueve donde está escribiendo en la página hacia la izquierda (o derecha si esa es su cultura)

\n es una nueva línea, que mueve su papel hacia arriba una línea.

Hacer solo uno de estos en una máquina de escribir lo colocaría en el lugar equivocado para comenzar a escribir una nueva línea de texto.

Cuando surgieron las computadoras, supongo que algunas personas conservaron el modelo anterior, pero otras se dieron cuenta de que no era necesario y encapsularon una nueva línea completa como un solo personaje.

Matt Ellen
fuente
77
Entonces, ¿por qué Windows todavía se adhiere a él?
sukhbir
8
Compatibilidad con versiones anteriores. Imagine cuántos documentos de texto se romperían si cambiaran ahora
Matt Ellen
44
Hablando estrictamente, el "bicho raro" aquí es el unixoide 'use newline only', inicialmente hecho (creo) para mantener baja la cantidad de caracteres almacenados (la traducción a CR LF se realiza en el controlador de terminal, es la bandera 'onlcr' que lo controla para la salida.
Vatine
3
Windows tenía un Predecesor llamado DOS, que tenía el mismo final de línea. Windows mantuvo compatibilidad. DOS tenía predecesores, es decir, CP / M. Eso también usó CRLF. DOS mantuvo la compatibilidad. El desarrollo de CP / M estuvo influenciado por DECs TOPS. Y se puede adivinar, qué lineending usaron. :-) La compatibilidad explica mucho.
Mnementh
55
Bien, pero ¿por qué el Bloc de notas todavía no reconoce las terminaciones de línea "\ n"?
dan04
8

No sé si esto es de conocimiento común, pero debe tenerse en cuenta que los emuladores de terminal modernos todavía entienden la RC:

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

Es útil para indicadores de progreso, p. Ej.

for i in {1..100}
do
    printf "\rLoading... %d%%" $i
    sleep 0.01
done
echo
Daniel Lubarov
fuente
1
En las antiguas impresoras de línea de IBM (p. Ej., La 1403), la convención era tratar el primer carácter del búfer de línea como un carácter de control de carro. En blanco para avanzar una línea e imprimir. Plus significaba omitir el espaciado y se usaba, por ejemplo, para subrayar. Un cero significaba doble espacio y un menos a triple espacio. Un '1' espaciado en la parte superior de la página siguiente, y otros dígitos avanzaron a posiciones verticales definidas por el usuario (utilizadas para completar formularios preimpresos).
George
7

Históricamente, el avance de línea significaba que la platina, el rodillo en el que escribía, giraba una línea, haciendo que el texto apareciera en la siguiente línea ... pero en la siguiente columna.

El retorno de carro significa "devolver el bit con el que escribe al principio de la línea".

Windows usa CR + LF porque MS-DOS lo hizo, porque CP / M lo hizo, porque tenía sentido para las líneas seriales.

Unix copió su \ n convención porque Multics lo hizo.

¡Sospecho que si profundizas lo suficiente, encontrarás un desacuerdo político entre los implementadores!

(Dejó de lado la parte extra de diversión, donde la convención Mac es (o solía ser) simplemente usar CR para separar líneas. ¡Y ahora Unicode también tiene su propio separador de línea, U + 2028!)

Frank Shearar
fuente
¡Guauu! no sabía sobre la Mac ...
Michael K
No estoy seguro de que encuentre un desacuerdo político. También es posible que encuentres personas haciendo cosas similares de forma independiente.
David Thornley
1
¿Cuándo hay diferentes organismos de normalización involucrados? ¡Me sorprendería no encontrar razones políticas!
Frank Shearar
6

Historia del personaje de Newline (Wikipedia):

ASCII fue desarrollado simultáneamente por ISO y ASA, la organización predecesora de ANSI. Durante el período de 1963-1968, los proyectos de normas ISO respaldaron el uso de CR + LF o LF solo como una nueva línea, mientras que los borradores ASA solo admitieron CR + LF.

La secuencia CR + LF era de uso común en muchos sistemas informáticos tempranos que habían adoptado máquinas de teletipo, típicamente un ASR33, como dispositivo de consola, porque esta secuencia era necesaria para colocar esas impresoras al comienzo de una nueva línea. En estos sistemas, el texto a menudo se componía habitualmente para ser compatible con estas impresoras, ya que el concepto de controladores de dispositivos que ocultaban dichos detalles de hardware de la aplicación aún no estaba bien desarrollado; Las aplicaciones tenían que hablar directamente con la máquina de teletipo y seguir sus convenciones.

La separación de las dos funciones ocultaba el hecho de que el cabezal de impresión no podía regresar desde el extremo derecho al comienzo de la siguiente línea en el tiempo de un carácter. Es por eso que la secuencia siempre se envió primero con el CR. De hecho, a menudo era necesario enviar caracteres adicionales (CR o NUL extraños, que se ignoran) para dar tiempo al cabezal de impresión para moverse al margen izquierdo.

Incluso después de que los teletipos fueron reemplazados por terminales de computadora con velocidades de transmisión más altas, muchos sistemas operativos aún admitían el envío automático de estos caracteres de relleno, por compatibilidad con terminales más baratos que requerían tiempos de caracteres múltiples para desplazar la pantalla.

MS-DOS (1981) adoptó CR + LF de CP / M; El uso de CP / M de CR + LF tenía sentido para usar terminales de computadora a través de líneas seriales. Esta convención fue heredada por el posterior sistema operativo Windows de Microsoft.

El sistema operativo Multics comenzó a desarrollarse en 1964 y usó LF solo como su nueva línea. Unix siguió la práctica de Multics, y los sistemas posteriores siguieron a Unix.

Craige
fuente
En el antiguo terminal de impresora-teclado IBM 2741, el componente de la impresora era una máquina de escribir de bolas de tipo rebote IBM Selectric. El cambio a mayúsculas provocó que la pelota girara, lo que tomó más tiempo. En el código de caracteres EBCDIC, los caracteres en mayúscula tenían 1 bit en la posición 6. Entonces, ¡un espacio en blanco EBCDIC (0x40) estaba en mayúscula! Si estaba imprimiendo un documento largo (por ejemplo, una tesis), podría acelerar materialmente la producción traduciendo espacios en blanco entre palabras en minúsculas a NUL o espacios en blanco en minúsculas (utilizaron un carácter diferente, IL si la memoria sirve, para introducir los retrasos necesarios, por ejemplo , al volver o tabular).
George
5

¿Qué pasa con la gente preguntando "por qué Unix puede hacer \ny no Windows"? Es una pregunta tan extraña.

  1. El sistema operativo no tiene casi nada que ver con eso. Es más una cuestión de cómo las aplicaciones, bibliotecas, protocolos y formatos de archivo manejan las cosas. Aparte de donde el sistema operativo lee / escribe la configuración basada en texto o los comandos de línea de comandos, no tiene sentido criticar el sistema operativo.
  2. La mayoría de las aplicaciones de Windows pueden leer ambas \ny \r\nmuy bien. También salen \r\npara que todos estén contentos. Un programa no se limita a "hacer", ya sea \no \r\n- se acepta uno, el otro, o ambos, y salidas de uno, el otro o ambos.
  3. Como programador, esto casi nunca debería molestarte. Prácticamente todos los idiomas / plataformas tienen facilidades para escribir la línea final correcta y leer con mayor solidez. La única vez que tuve que lidiar con el problema fue cuando escribí un servidor HTTP , y fue porque cierto navegador (pista: el siguiente navegador más popular después de IE) estaba funcionando en \nlugar del correcto \r\n .
  4. Una pregunta mucho más pertinente es, ¿por qué tantas aplicaciones modernas de Unix salen solo \nsabiendo que hay algunos protocolos y programas que no les gustan?
Rei Miyasaka
fuente
3
Otra pregunta pertinente: dado que muchos protocolos se desarrollaron principalmente en sistemas Unix, ¿por qué no usaron '\ n'?
David Thornley
@DavidThornley Porque es más probable que \ r \ n funcione multiplataforma (\ r para equipos Mac más antiguos, \ r \ n para Windows y \ n para * nix).
Básico
4

La razón por la cual las convenciones se mantienen en sus diversos sistemas (\ n en sistemas de tipo unix, \ r \ n en Windows, etc.) es que una vez que ha elegido una convención, NO PUEDE cambiarla sin romper un montón de archivos de personas. Y eso generalmente está mal visto.

Los sistemas de tipo Unix se desarrollaron (en los primeros días) utilizando varios modelos de teletipo, y en algún momento alguien decidió que el equipo debería devolver el carro cuando realizaba un avance de línea.

Windows vino de DOS, así que para Windows la pregunta realmente es: ¿Por qué DOS usó esta secuencia cr / lf? Supongo que tiene algo que ver con CP / M, donde DOS tiene algunas de sus raíces. Una vez más, los modelos específicos de teletipo pueden haber jugado un papel.

Michael Kohne
fuente
Mmmm interesante.
sukhbir
1
¿Por qué Windows no puede manejar líneas que terminan en \n, pero continúan usándolas \r\npor ahora? Si lo hicieron a partir de Windows XP, ahora podrían comenzar a guardar archivos en \nlugar de \r\n.
DisgruntledGoat
1
Windows no tiene nada que ver con eso. Es la decisión de las aplicaciones, y la mayoría de las aplicaciones leerán '\ n' y '\ r \ n', y escribirán '\ r \ n', para que todos estén contentos.
Rei Miyasaka
2

Aquí hay una respuesta de la mejor fuente: Microsoft. ¿Por qué el terminador de línea CR + LF?

Este protocolo se remonta a los días de los teletipos. CR significa "retorno de carro": el carácter de control CR devolvió el cabezal de impresión ("carro") a la columna 0 sin avanzar el papel. LF significa "salto de línea": el carácter de control de LF avanzó el papel una línea sin mover el cabezal de impresión. Entonces, si desea devolver el cabezal de impresión a la columna cero (listo para imprimir la siguiente línea) y avanzar el papel (para que se imprima en papel nuevo), necesita CR y LF.

Si va a varios documentos de protocolo de Internet, como RFC 0821 (SMTP), RFC 1939 (POP), RFC 2060 (IMAP) o RFC 2616 (HTTP), verá que todos especifican CR + LF como secuencia de terminación de línea. Entonces, la verdadera pregunta no es "¿Por qué CP / M, MS-DOS y Win32 usan CR + LF como terminador de línea?" sino "¿Por qué otras personas optaron por diferir de estos documentos estándar y utilizar algún otro terminador de línea?"

Unix adoptó LF simple como la secuencia de terminación de línea. Si observa las opciones stty, verá que la opción onlcr especifica si un LF debe cambiarse a CR + LF. Si se equivoca esta configuración, aparece el texto de la escalera, donde

each
    line
        begins

donde dejó la línea anterior. Entonces, incluso Unix, cuando se deja en modo sin procesar, requiere CR + LF para terminar las líneas. El CR implícito antes de LF es una invención de Unix, probablemente como una economía, ya que ahorra un byte por línea.

La ascendencia de Unix del lenguaje C llevó esta convención al estándar del lenguaje C, que requiere solo "\ n" (que codifica LF) para terminar las líneas, poniendo la carga en las bibliotecas de tiempo de ejecución para convertir datos de archivos sin procesar en líneas lógicas.

El lenguaje C también introdujo el término "nueva línea" para expresar el concepto de "terminador de línea genérico". Me dijeron que el comité ASCII cambió el nombre del personaje 0x0A a "nueva línea" alrededor de 1996, por lo que el nivel de confusión se ha elevado aún más.

Ondra Žižka
fuente