"std::endl" frente a "\n"
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?
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::endl
vací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
.
La diferencia se puede ilustrar con lo siguiente:
std::cout << std::endl;
es equivalente a
std::cout << '\n' << std::flush;
Entonces,
- Úselo
std::endl
si desea forzar una descarga inmediata a la salida. - Úselo
\n
si le preocupa el rendimiento (que probablemente no sea el caso si está utilizando el<<
operador).
Lo uso \n
en la mayoría de las líneas.
Luego utilícelo std::endl
al final de un párrafo (pero eso es solo un hábito y generalmente no es necesario).
Contrariamente a otras afirmaciones, el \n
carácter se asigna a la secuencia correcta de final de línea de la plataforma solo si la secuencia va a un archivo ( std::cin
y std::cout
es especial pero sigue siendo archivos (o similar a un archivo)).
Puede haber problemas de rendimiento que std::endl
obliguen a un vaciado del flujo de salida.
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.
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::cout
y std::cin
está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::endl
menos que canalice a archivos: c++ ref en std::endl .