¿Cuál es la diferencia entre \ r y \ n?

¿Cómo son \r y \n diferentes? Creo que tiene algo que ver con Unix vs. Windows vs. Mac, pero no estoy seguro de cómo son diferentes y qué buscar / combinar en expresiones regulares.

Son personajes diferentes. \r es el retorno de carro, y \n es avance de línea.

En impresoras “antiguas”, devolvió el cabezal de impresión al inicio de la línea y \n avanzó el papel en una línea. Ambos fueron necesarios para comenzar a imprimir en la siguiente línea.

Obviamente, eso es algo irrelevante ahora, aunque dependiendo de la consola, todavía puedes usar \r para moverte al inicio de la línea y sobrescribir el texto existente.

Más importante aún, Unix tiende a usar \n como un separador de línea; Windows tiende a usar \r\n como un separador de línea y Macs (hasta OS 9) solía usar \r como el separador de línea. (Mac OS X es Unix-y, por lo tanto, usa \n ; sin embargo, puede haber algunas situaciones de compatibilidad donde se usa \r ).

Para obtener más información, consulte el artículo de nueva línea de Wikipedia .

EDITAR: Esto es sensible al lenguaje. En C # y Java, por ejemplo, \n siempre significa Unicode U + 000A, que se define como avance de línea. En C y C ++, el agua está algo turbia, ya que el significado es específico de la plataforma. Ver comentarios para más detalles.

En C y C ++, \n es un concepto, \r es un carácter y \r\n es (casi siempre) un error de portabilidad.

Piensa en un viejo teletipo. El cabezal de impresión está posicionado en alguna línea y en alguna columna. Cuando envía un carácter imprimible al teletipo, imprime el carácter en la posición actual y mueve el encabezado a la siguiente columna. (Esto es conceptualmente lo mismo que una máquina de escribir, excepto que las máquinas de escribir típicamente movieron el papel con respecto al cabezal de impresión).

Cuando quería terminar la línea actual y comenzar en la siguiente línea, tenía que hacer dos pasos por separado:

  1. mueva el cabezal de impresión nuevamente al comienzo de la línea, luego
  2. moverlo a la siguiente línea.

ASCII codifica estas acciones como dos caracteres de control distintos:

  • \x0D (CR) mueve el cabezal de impresión de vuelta al principio de la línea. (Unicode codifica esto como U+000D CARRIAGE RETURN ).
  • \x0A (LF) mueve el cabezal de impresión a la siguiente línea. (Unicode codifica esto como U+000A LINE FEED ).

En la época de los teletipos y los primeros impresores de tecnología, la gente realmente aprovechaba el hecho de que se trataba de dos operaciones separadas. Al enviar un CR sin seguirlo por un LF, puede imprimir sobre la línea que ya imprimió. Esto permitió efectos como acentos, negrita y subrayado. Algunos sistemas se sobreimprimen varias veces para evitar que las contraseñas sean visibles en copia impresa. En los primeros terminales CRT en serie, CR era una de las formas de controlar la posición del cursor para actualizar el texto que ya estaba en la pantalla.

Pero la mayoría de las veces, en realidad solo querías ir a la siguiente línea. En lugar de requerir el par de caracteres de control, algunos sistemas permitían solo uno u otro. Por ejemplo:

  • Las variantes de Unix (incluidas las versiones modernas de Mac) usan solo un carácter LF para indicar una nueva línea.
  • Los archivos antiguos (pre-OSX) de Macintosh usaban solo un carácter de CR para indicar una nueva línea.
  • VMS, CP / M, DOS, Windows y muchos protocolos de red aún esperan ambos: CR LF.
  • Sistemas antiguos de IBM que usaban EBCDIC estandarizados en NL, un carácter que ni siquiera existe en el juego de caracteres ASCII. En Unicode, NL es U+0085 NEXT LINE , pero el valor EBCDIC real es 0x15 .

¿Por qué los diferentes sistemas eligen diferentes métodos? Simplemente porque no había un estándar universal. Donde su teclado probablemente dice “Enter”, los teclados antiguos solían decir “Volver”, que era la abreviación de Carriage Return. De hecho, al presionar Retorno, en realidad, envía el carácter CR. Si estuvieras escribiendo un editor de texto, sería tentador simplemente usar ese carácter desde el terminal. Quizás es por eso que los Macs más antiguos usaban solo CR.

Ahora que tenemos estándares , hay más formas de representar saltos de línea. Aunque es extremadamente raro en la naturaleza, Unicode tiene nuevos personajes como:

  • U+2028 LINE SEPARATOR
  • U+2029 PARAGRAPH SEPARATOR

Incluso antes de que llegara Unicode, los progtwigdores querían formas simples de representar algunos de los códigos de control más útiles sin preocuparse por el conjunto de caracteres subyacente. C tiene varias secuencias de escape para representar códigos de control:

  • \a (para alerta) que suena la campana de teletipo o hace que el terminal emita un pitido
  • \f (para alimentación de formulario) que se mueve al comienzo de la página siguiente
  • \t (para tabulación) que mueve el cabezal de impresión a la siguiente posición de pestaña horizontal

(Esta lista es intencionalmente incompleta)

Este mapeo ocurre en tiempo de comstackción, el comstackdor ve \a y pone cualquier valor mágico que se use para tocar el timbre.

Tenga en cuenta que la mayoría de estas mnemotécnicas tienen correlaciones directas con los códigos de control ASCII. Por ejemplo, \a se correlacionaría con 0x07 BEL . Se podría escribir un comstackdor para un sistema que utilizaba algo distinto a ASCII para el conjunto de caracteres del host (por ejemplo, EBCDIC). La mayoría de los códigos de control que tenían mnemónicos específicos se podían asignar a códigos de control en otros conjuntos de caracteres.

¡Hurra! ¡Portabilidad!

Bueno, casi. En C, podría escribir printf("\aHello, World!"); que suena el timbre (o suena) y emite un mensaje. Pero si quisiera imprimir algo en la próxima línea, aún necesitaría saber qué necesita la plataforma de host para pasar a la próxima línea de salida. CR LF? CR? LF? NL? ¿Algo más? Demasiado para la portabilidad.

C tiene dos modos para E / S: binario y texto. En modo binario, cualquier información que se envíe se transmite tal cual. Pero en el modo texto, hay una traducción en tiempo de ejecución que convierte un carácter especial a lo que la plataforma host necesita para una nueva línea (y viceversa).

Genial, ¿cuál es el personaje especial?

Bueno, eso también depende de la implementación, pero hay una forma independiente de implementación para especificarlo: \n . Generalmente se llama el “personaje de nueva línea”.

Este es un punto sutil pero importante: \n se asigna en tiempo de comstackción a un valor de carácter definido por implementación que (en modo texto) se vuelve a asignar en el tiempo de ejecución al carácter real (o secuencia de caracteres) requerido por la plataforma subyacente para pasar a la siguiente línea.

\n es diferente a todos los otros literales de barra invertida porque hay dos mapeos involucrados. Este mapeo en dos pasos hace que \n significativamente diferente que even \r , que es simplemente un mapeo en tiempo de comstackción para CR (o el código de control más similar en cualquiera que sea el conjunto de caracteres subyacente).

Esto dispara muchos progtwigdores C y C ++. Si tuviera que sondear a 100 de ellos, al menos 99 le dirán que \n significa alimentación de línea. Esto no es enteramente verdad. La mayoría (quizás todas) las implementaciones C y C ++ usan LF como el valor intermedio mágico para \n , pero eso es un detalle de implementación. Es factible que un comstackdor use un valor diferente. De hecho, si el conjunto de caracteres del host no es un superconjunto de ASCII (por ejemplo, si es EBCDIC), \n seguramente no será LF.

Entonces, en C y C ++:

  • es literalmente un retorno de carro.
  • \n es un valor mágico que se traduce (en modo texto) en tiempo de ejecución hacia / desde la semántica de línea nueva de la plataforma de host.
  • \r\n casi siempre es un error de portabilidad. En modo texto, esto se traduce a CR seguido de la secuencia de nueva línea de la plataforma, probablemente no lo que se pretende. En el modo binario, esto se traduce en CR seguido de algún valor mágico que podría no ser LF, posiblemente no lo que se pretende.
  • \x0A es la manera más portátil de indicar un ASCII LF, pero solo quiere hacer eso en modo binario. La mayoría de las implementaciones en modo texto tratarán eso como \n .
  • “\ r” => Volver
  • “\ n” => Newline o Linefeed (semántica)

  • Los sistemas basados ​​en Unix usan solo “\ n” para finalizar una línea de texto.

  • Dos usa “\ r \ n” para finalizar una línea de texto.
  • Algunas otras máquinas utilizan solo una “\ r”. (Commodore, Apple II, Mac OS antes de OS X, etc.)

En resumen, \ r tiene el valor ASCII 13 (CR) y \ n tiene el valor ASCII 10 (LF). Mac utiliza CR como delimitador de línea (al menos, lo hizo antes, no estoy seguro de macs modernos), * nix usa LF y Windows usa ambos (CRLF).

\r se usa para señalar el inicio de una línea y puede reemplazar el texto desde allí, por ejemplo

 main() { printf("\nab"); printf("\bsi"); printf("\rha"); } 

Produce este resultado:

 hai 

\n es para nueva línea.

Además de la respuesta de @Jon Skeet:

Tradicionalmente Windows ha usado \ r \ n, Unix \ n y Mac \ r, sin embargo, los Mac más nuevos usan \ n ya que están basados ​​en Unix.

en C # encontré que usan \ r \ n en una cadena.

es el retorno de carro; \ n es New Line (Line Feed) … depende del sistema operativo en cuanto a lo que cada uno significa. Lea este artículo para obtener más información sobre la diferencia entre ‘\ n’ y ‘\ r \ n’ … en C.

\ r usado para el retorno de carro. (El valor ASCII es 13) \ n usado para una nueva línea. (El valor ASCII es 10)