2009-08-14 24 views
201

¿En qué se diferencian \r y \n? 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.¿Cuál es la diferencia entre r y n?

+1

Esto necesita una etiqueta de idioma. Los diferentes idiomas tienen diferentes interpretaciones de ''\ n''. –

Respuesta

314

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

En impresoras "antiguas", \r 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, ahora es algo irrelevante, aunque dependiendo de la consola, todavía puede utilizar \r para pasar 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 separador de línea y Mac (hasta OS 9) utilizado para usar \r como separador de línea. (Mac OS X es Unix-y, por lo usa \n lugar, puede haber algunas situaciones de compatibilidad cuando se usa en lugar \r sin embargo.)

Para obtener más información, consulte la Wikipedia newline article.

EDITAR: Esto es sensible al idioma. En C# y Java, por ejemplo, \nsiempre 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.

+19

+1 para personas mayores. Salida de terminal utilizada para controlar directamente un terminal electrónico glorificado (su TTY antes de esas elegantes pantallas CRT). Por lo tanto, obtenemos maravillosos artefactos de aquellos en el retorno de carro y caracteres de nueva línea (los cuales podrían ser necesarios, como mencionó Jon Skeet) y cosas como \ "campana", \ b "retroceso" (no debe confundirse con "eliminar" "), y todos los otros personajes de control necesarios para comunicarse con un tty. – erjiang

+35

Otro +1 para personas mayores. Todavía puede presionar Ctrl + G en el símbolo del sistema de Windows, presionar enter, y el parlante de la PC emitirá un pitido. Eso ha quedado de la antigüedad. –

+0

@Crappy Coding Guy realmente? En Vista, solo dice "'' no se reconoce como un comando interno o externo" – Ponkadoodle

2

\ r es Carriage Return; \ n es New Line (Line Feed) ... depende del sistema operativo en cuanto a lo que cada uno significa. Lea esto article para obtener más información sobre la diferencia entre '\ n' y '\ r \ n' ... en C.

4

En resumen, \ r tiene valor ASCII 13 (CR) y \ n tiene 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).

+1

Los sistemas Mac OS X usan LF por defecto (ya que está basado en BSD Unix). – dreamlax

3

Además de la respuesta de @ Jon Skeet:

Tradicionalmente Windows ha utilizado \ r \ n, Unix \ n y Mac \ r, sin embargo los nuevos ordenadores Mac usar \ n y cuando estén basados ​​en Unix.

9
  • "\ r" => Vuelta
  • "\ n" => Newline o avance de línea (semántica)

  • Unix basan sistemas utilizan sólo un "\ n" para poner fin a una línea de texto.

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

En C y C++, \n es un concepto, \r es un personaje, y \r\n es (casi siempre) un error portabilidad.

Piense 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 normalmente 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 separadamente pasos:

  1. mover el cabezal de impresión de nuevo al principio de la línea, a continuación,
  2. moverlo hacia abajo a la siguiente línea.

ASCII codifica estas acciones como dos caracteres de control distintas:

  • \x0D (CR) se mueve el cabezal de impresión de nuevo 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 los días de teletipos y las impresoras de tecnología principios, la gente realmente se aprovecharon del 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ía pasar 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) utilizan solo un carácter LF para indicar una nueva línea.
  • Los archivos antiguos (pre-OSX) de Macintosh utilizan solo un carácter CR para indicar una nueva línea.
  • VMS, CP/M, DOS, Windows, y muchos protocolos de red todavía 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 standards, hay más formas de representar los 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 Unicode llegó, los programadores querían formas sencillas para representar algunos de los códigos de control más útiles, sin Preocuparse por el juego de caracteres subyacente. C tiene varias secuencias de escape para la representación de los códigos de control:

  • \a (para la alerta), que toca la campana teletipo o hace que el pitido terminal de
  • \f (para la alimentación de forma), que se mueve al comienzo de la página siguiente
  • \t (por ficha) que se mueve el cabezal de impresión a la siguiente posición pestaña horizontal

(Esta lista es intencionalmente incompleta.)

Este mapeo ocurre en en tiempo de compilación --el compilador ve \a y pone el valor mágico que se usa para hacer sonar la campana.

Observe que la mayoría de estos mnemotécnicos tienen correlaciones directas con los códigos de control ASCII. Por ejemplo, \a se correlacionaría con 0x07 BEL. Se podría escribir un compilador para un sistema que utilizaba algo distinto a ASCII para el juego 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 de 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 carácter 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 al tiempo de compilación a un valor de carácter definido por la implementación que (en modo texto) está a continuación, asigna otra vez en tiempo de ejecución al carácter real (o secuencia de caracteres) requerida por la plataforma subyacente para pasar a la siguiente línea.

\n es diferente a todos los demás literales de barra invertida porque hay dos asignaciones involucradas.Este mapeo en dos pasos hace que \n sea significativamente diferente que incluso \r, que es simplemente un mapeo en tiempo de compilación para CR (o el código de control más similar en cualquier conjunto de caracteres subyacente).

Esto dispara muchos programadores de 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 compilador use un valor diferente. De hecho, si el conjunto de caracteres del host no es un superconjunto de ASCII (por ejemplo, si es EBCDIC), entonces \n casi con certeza no será LF.

Así, en C y C++:

  • \r es, literalmente, un retorno de carro.
  • \n es un valor mágico que se traduce (en modo texto) al en tiempo de ejecución a/desde la semántica de nueva línea de la plataforma del host.
  • \r\n es casi siempre 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 modo binario, esto se traduce en CR seguido de algún valor mágico que podría no ser ser LF, posiblemente no lo que se pretende.
  • \x0A es la forma más portátil de indicar un ASCII LF, pero solo desea hacer eso en modo binario. La mayoría de las implementaciones en modo texto tratarán eso como \n.
4

\r se utiliza para señalar el comienzo de una línea y se puede reemplazar el texto a partir de ahí, por ejemplo,

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

Produce esta salida:

hai 

\n es para la nueva línea.

2

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

1

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

Cuestiones relacionadas