¿Cuál es la diferencia entre y ?


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

Author: Artemis, 2009-08-14

9 answers

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

En impresoras "antiguas", \r envió el cabezal de impresión de nuevo al comienzo de la línea, y \n adelantó el papel en una línea. Por lo tanto, ambos eran necesarios para comenzar a imprimir en la siguiente línea.

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

Más es importante destacar que Unix tiende a usar \n como separador de líneas; Windows tiende a usar \r\n como separador de líneas y Macs (hasta OS 9) usa para usar \r como separador de líneas. (Mac OS X es Unix-y, por lo que usa \n en su lugar; sin embargo, puede haber algunas situaciones de compatibilidad donde se usa \r en su lugar.)

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

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

 328
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-03 21:46:49

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 se coloca 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 la cabeza a la siguiente columna. (Esto es conceptualmente lo mismo que una máquina de escribir, excepto que las máquinas de escribir normalmente movían el papel con respecto a la impresión cabeza.)

Cuando querías terminar la línea actual y comenzar en la siguiente línea, tenías que hacer dos pasos separados:

  1. mueva el cabezal de impresión de nuevo al principio de la línea, luego
  2. muévelo hacia abajo a la siguiente línea.

ASCII codifica estas acciones como dos caracteres de control distintos:

  • \x0D (CR) 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 baja a la siguiente línea. (Unicode codifica esto como U+000A LINE FEED.)

En los días de los teletipos y las primeras impresoras de tecnología, la gente en realidad se aprovechaba del hecho de que estas eran 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 sobreimprimieron varias veces para evitar que las contraseñas fueran visibles en papel. En CRT serie temprana terminales, CR era una de las formas de controlar la posición del cursor con el fin de actualizar el texto ya 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 (incluyendo 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 CR para indica una nueva línea.
  • Las máquinas virtuales, CP/M, DOS, Windows y muchos protocolos de red todavía esperan ambos: CR LF.
  • Sistemas IBM antiguos que usaban EBCDIC estandarizados en NL a un carácter que ni siquiera existe en el conjunto de caracteres ASCII. En Unicode, NL es U+0085 NEXT LINE, pero el valor EBCDIC real es 0x15.

¿Por qué diferentes sistemas eligieron diferentes métodos? Simplemente porque no había un estándar universal. Donde el teclado probablemente dice "Enter", más viejo los teclados solían decir "Retorno", que era la abreviatura de Retorno de carro. De hecho, en un terminal serie, al presionar Retorno en realidad se envía el carácter CR. Si estuviera escribiendo un editor de texto, sería tentador usar ese carácter tal y como llegó desde la 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 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 que llegara Unicode, los programadores 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 hace sonar la campana del teletipo o hace sonar el pitido terminal
  • \f (para el formulario de alimentación) que se mueve al principio de la siguiente page
  • \t (para tabulación) que mueve el cabezal de impresión a la siguiente posición horizontal de tabulación

(Esta lista es intencionalmente incompleta.)

Esta asignación ocurre en tiempo de compilación the el compilador ve \a y pone cualquier valor mágico que se use 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 asignaría a 0x07 BEL. Un compilador podría ser escrito para un sistema que utiliza algo que no sea ASCII para el conjunto de caracteres del host (por ejemplo, EBCDIC). La mayoría de los códigos de control que tenían mnemotécnica específica se podían asignar a códigos de control en otros conjuntos de caracteres.

Huzzah! La portabilidad!

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

C tiene dos modos para E/S: binario y texto. En modo binario, cualquier dato 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 anfitriona necesite para una nueva línea (y viceversa).

Genial, entonces, ¿cuál es el carácter especial?

Bueno, eso también depende de la implementación, pero hay una forma de especificar independiente de la implementación it: \n. Normalmente se llama el "carácter de nueva línea".

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

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

Esto hace tropezar a muchos programadores de C y C++. Si usted fuera a sondear 100 de ellos, al menos 99 le dirá que \n significa alimentación de línea. Esto no es del todo cierto. La mayoría (quizás todas) las implementaciones de 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 seguramente no será LF.

Así que, en C y C++:

  • \r es literalmente un retorno de carro.
  • \n es un valor mágico que se traduce (en modo texto) en tiempo de ejecución a/desde la semántica de nueva línea de la plataforma host.
  • \r\n es casi siempre una portabilidad error. En el modo texto, esto se traduce a CR seguido por la secuencia de nueva línea de la plataforma probably probablemente no lo que se pretende. En modo binario, esto se traduce a CR seguido de algún valor mágico que podría no ser LF possibly posiblemente no lo que se pretende.
  • \x0A es la forma más portátil de indicar un ASCII LF, pero solo desea hacerlo en modo binario. La mayoría de las implementaciones en modo texto lo tratarán como \n.
 82
Author: Adrian McCarthy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-12 16:38:20
  • "\r " = > Return
  • "\n " = > Nueva línea o Salto de línea (semántica)

  • Los sistemas basados en Unix usan solo una "\n " para terminar una línea de texto.

  • Dos usa "\r\n" para terminar una línea de texto.
  • Algunas otras máquinas usaban solo un "\r". (Commodore, Apple II, Mac OS anterior a OS X, etc..)
 9
Author: NoMoreZealots,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-14 20:37:21

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

 4
Author: Josip Medved,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-14 19:41:34

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

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

Produce esta salida:

hai

\n es para nueva línea.

 4
Author: DAYA PHILIP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-17 04:27:49

Además de la respuesta de @Jon Skeet:

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

 3
Author: Greg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-14 19:42:34

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

 2
Author: wesley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-18 08:44:36

\r es Retorno de carro; \n es Nueva Línea (Avance de línea) ... 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.

 2
Author: Nathan Loding,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-27 11:49:09

\r utilizado para el retorno de carro. (El valor ASCII es 13) \ n se utiliza para la nueva línea. (El valor ASCII es 10)

 1
Author: Manjeet Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-09 08:25:24