"std::endl" frente a "\n"

Resuelto Head Geek asked hace 16 años • 12 respuestas

Muchos libros de C++ contienen código de ejemplo como este...

std::cout << "Test line" << std::endl;

...así que siempre he hecho eso también. Pero he visto una gran cantidad de código de desarrolladores en activo como este:

std::cout << "Test line\n";

¿Existe alguna razón técnica para preferir uno sobre el otro, o es sólo una cuestión de estilo de codificación?

Head Geek avatar Oct 18 '08 04:10 Head Geek
Aceptado

Los diferentes caracteres al final de línea no importan, suponiendo que el archivo esté abierto en modo texto, que es lo que obtiene a menos que solicite binario. El programa compilado escribirá lo correcto para el sistema compilado.

La única diferencia es que std::endlvacía el búfer de salida y '\n'no lo hace. Si no desea que el búfer se vacíe con frecuencia, utilice '\n'. Si lo hace (por ejemplo, si desea obtener todos los resultados y el programa es inestable), utilice std::endl.

David Thornley avatar Oct 17 '2008 21:10 David Thornley

La diferencia se puede ilustrar con lo siguiente:

std::cout << std::endl;

es equivalente a

std::cout << '\n' << std::flush;

Entonces,

  • Úselo std::endlsi desea forzar una descarga inmediata a la salida.
  • Úselo \nsi le preocupa el rendimiento (que probablemente no sea el caso si está utilizando el <<operador).

Lo uso \nen la mayoría de las líneas.
Luego utilícelo std::endlal final de un párrafo (pero eso es solo un hábito y generalmente no es necesario).

Contrariamente a otras afirmaciones, el \ncarácter se asigna a la secuencia correcta de final de línea de la plataforma solo si la secuencia va a un archivo ( std::ciny std::coutes especial pero sigue siendo archivos (o similar a un archivo)).

Martin York avatar Oct 17 '2008 22:10 Martin York

Puede haber problemas de rendimiento que std::endlobliguen a un vaciado del flujo de salida.

Martin Beckett avatar Oct 17 '2008 21:10 Martin Beckett

Hay otra llamada a función implícita allí si vas a usarstd::endl

a) std::cout << "Hello\n";
b) std::cout << "Hello" << std::endl;

a) llama al operador <<una vez.
b) llama al operador <<dos veces.

Nathan avatar Nov 17 '2009 22:11 Nathan

Recordé haber leído sobre esto en el estándar, así que aquí va:

Consulte el estándar C11 que define cómo se comportan los flujos estándar, ya que los programas C++ interactúan con el CRT, el estándar C11 debería regir la política de vaciado aquí.

ISO/CEI 9899:201x

7.21.3 §7

Al iniciar el programa, hay tres secuencias de texto predefinidas y no es necesario abrirlas explícitamente: entrada estándar (para leer la entrada convencional), salida estándar (para escribir la salida convencional) y error estándar (para escribir la salida de diagnóstico). Tal como se abrió inicialmente, el flujo de error estándar no está completamente almacenado en el búfer; los flujos de entrada estándar y de salida estándar se almacenan completamente en el buffer si y solo si se puede determinar que el flujo no hace referencia a un dispositivo interactivo.

7.21.3 §3

Cuando una transmisión no tiene búfer, se pretende que los personajes aparezcan desde el origen o el destino lo antes posible. De lo contrario, los caracteres pueden acumularse y transmitirse hacia o desde el entorno anfitrión como un bloque. Cuando una secuencia está completamente almacenada en el búfer, los caracteres deben transmitirse hacia o desde el entorno del host como un bloque cuando se llena el búfer. Cuando una secuencia tiene un búfer de línea, los caracteres deben transmitirse hacia o desde el entorno del host como un bloque cuando se encuentra un carácter de nueva línea. Además, los caracteres están destinados a transmitirse como un bloque al entorno del host cuando se llena un búfer, cuando se solicita una entrada en una secuencia sin búfer o cuando se solicita una entrada en una secuencia con búfer de línea que requiere la transmisión de caracteres desde el entorno del host. . El soporte para estas características está definido por la implementación y puede verse afectado a través de las funciones setbuf y setvbuf.

Esto significa que std::couty std::cinestán completamente almacenados en el buffer si y solo si se refieren a un dispositivo no interactivo. En otras palabras, si stdout está conectado a una terminal, entonces no hay diferencia en el comportamiento.

Sin embargo, si std::cout.sync_with_stdio(false)se llama, '\n'no provocará un lavado ni siquiera en los dispositivos interactivos. De lo contrario, '\n'es equivalente a std::endlmenos que canalice a archivos: c++ ref en std::endl .

Emily L. avatar Aug 29 '2014 13:08 Emily L.