“std::endl” frente a “\n”

4 minutos de lectura

stdendl frente a n
Jefe friki

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 mucho código de desarrolladores que trabajan como este:

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

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

  • Buena explicación: cppkid.wordpress.com/2008/08/27/por-que-prefiero-n-a-stdendl

    Molino de Payton

    17 de octubre de 2008 a las 21:28

  • @derobert este es mayor que el otro

    – Kira

    13 de noviembre de 2013 a las 15:31

  • @HediNaily de hecho lo es. Pero la respuesta en el otro me parece un poco mejor, así que elegí hacerlo de esa manera. Además, el otro es un poco más ancho, cubriendo también '\n'.

    – derobert

    13 de noviembre de 2013 a las 15:35


  • stackoverflow.com/a/30968225/3163618 puede haber una diferencia de rendimiento significativa.

    – qwr

    24 de marzo de 2020 a las 4:38

stdendl frente a n
david thornley

Los diferentes caracteres de final de línea no importan, suponiendo que el archivo esté abierto en modo de 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 Si no desea que el búfer se vacíe con frecuencia, use '\n'. Si lo hace (por ejemplo, si desea obtener toda la salida y el programa es inestable), utilice std::endl.

  • O considere usar ::std::cerr en lugar de ::std::cout ya que no tiene búfer y se vacía con todas y cada una de las operaciones de salida.

    – Omnifaro

    23 de enero de 2010 a las 11:45

  • @Omnifarious: No se debe reservar std::cerr para errores. Las dos transmisiones no están sincronizadas juntas, por lo que si genera algún texto para cout, es posible que se almacene en el búfer y el cerr irá directamente a la salida, lo que resultará en una visualización de modo mixto. Use cerr para lo que se supone que es (errores) y cout para lo que está diseñado (interacción normal).

    – Martín York

    3 de febrero de 2010 a las 16:39

  • @Lucas: No más que ‘\ n’ es consciente de la plataforma.

    –CB Bailey

    17 de febrero de 2010 a las 7:39

  • @LokiAstari: Yo no diría stderr es para “errores”. Más bien, es para mensajes de diagnóstico fuera de banda, por así decirlo. Debería ser posible decir ./prog > file y almacenar solo la carga real del programa, pero es posible que al programa le guste generar mucha más información de estado, incluso en una interacción normal.

    – KerrekSB

    28 de noviembre de 2011 a las 3:01

  • “En muchas implementaciones, la salida estándar tiene un búfer de línea, y escribir ‘\n’ provoca un vaciado de todos modos, a menos que se haya ejecutado std::cout.sync_with_stdio(false)”. copiado de aquí

    – GuLearn

    13 de agosto de 2013 a las 21:01

1647631391 672 stdendl frente a n
martín york

La diferencia se puede ilustrar con lo siguiente:

std::cout << std::endl;

es equivalente a

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

Entonces,

  • Utilizar std::endl Si desea forzar un vaciado inmediato de la salida.
  • Utilizar \n si está preocupado por el rendimiento (que probablemente no sea el caso si está utilizando el << operador).

yo suelo \n en la mayoría de las líneas.
Entonces usa std::endl al final de un párrafo (pero eso es solo un hábito y no suele ser necesario).

Contrariamente a otras afirmaciones, el \n el carácter se asigna a la secuencia de fin de línea de la plataforma correcta solo si la transmisión va a un archivo (std::cin y std::cout siendo especiales pero todavía archivos (o similares a archivos)).

  • En muchos casos, el “ver la salida inmediatamente” es una pista falsa, ya que cout está atado a cinlo que significa que si lee la entrada de cin, cout se enjuagará primero. Pero si desea mostrar una barra de progreso o algo sin leer desde cinentonces seguro, el lavado es útil.

    – Chris Jester-Young

    30 de marzo de 2011 a las 5:55

  • @LokiAstari: si está utilizando el operador <<, probablemente no esté preocupado por el rendimiento – ¿por qué? no sabia eso operator<< no es eficaz, o qué alternativa usar para el rendimiento? Por favor, indícame algún material para entender esto mejor.

    – leyendas2k

    22 de enero de 2014 a las 7:33


  • @legends2k: Hay un cuento de viejas que dice que los flujos de C++ no son tan eficaces como C printf(). Aunque es cierto hasta cierto punto, la principal diferencia en la velocidad es causada por personas que usan flujos de C ++ incorrectamente. stackoverflow.com/a/1042121/14065 En C++ recuerde desincronizar iostreams con C-streams sync_with_stdio(false) y no vacíe su salida continuamente. Deje que la biblioteca resuelva cuándo hacerlo. stackoverflow.com/a/1926432/14065

    – Martín York

    22 de enero de 2014 a las 19:53


  • @Loki: Hay una leyenda urbana que sync_with_stdio hace que iostreams sea tan rápido como stdio. No es asi

    – Ben Voigt

    15/09/2015 a las 16:30

  • @BenVoigt: Tuve cuidado con mi redacción anterior (así que estoy contento con ellos). No es tan eficaz como stdio (porque hace más). PERO gran parte de la brecha de rendimiento de la que la gente se queja se debe a la sincronización con stdio.

    – Martín York

    15/09/2015 a las 20:43

1647631392 278 stdendl frente a n
Martín Beckett

Puede haber problemas de rendimiento, std::endl fuerza una descarga del flujo de salida.

  • Y puede realizar cualquier otro procesamiento que requiera el sistema local para que esto funcione bien.

    – dmckee — gatito ex-moderador

    17/10/2008 a las 21:32

1647631392 620 stdendl frente a n
emily l

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 debe regir la política de vaciado aquí.

ISO/CEI 9899:201x

7.21.3 §7

Al iniciar el programa, hay tres flujos de texto predefinidos y no es necesario abrirlos 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á totalmente almacenado en el búfer; los flujos de entrada estándar y de salida estándar se almacenan en búfer completos si y solo si se puede determinar que el flujo no hace referencia a un dispositivo interactivo.

7.21.3 §3

Cuando una secuencia no está almacenada en búfer, los caracteres deben aparecer desde el origen o en 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 un flujo está completamente almacenado en el búfer, los caracteres deben transmitirse hacia o desde el entorno del host como un bloque cuando se llena un búfer. Cuando un flujo 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 un flujo sin búfer o cuando se solicita una entrada en un flujo 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 amortiguados si y solo si se refieren a un dispositivo no interactivo. En otras palabras, si stdout está conectado a una terminal, no hay diferencia en el comportamiento.

Sin embargo, si std::cout.sync_with_stdio(false) se llama, entonces '\n' no causará una descarga incluso en los dispositivos interactivos. De lo contrario '\n' es equivalente a std::endl a menos que se conecte a archivos: referencia c++ en std::endl.

1647631392 425 stdendl frente a n
natan

Hay otra llamada de función implícita allí si vas a usar std::endl

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

a) operador de llamadas << una vez.
b) operador de llamadas << dos veces.

  • Puede ser obvio, pero tiene un gran impacto en los programas con subprocesos donde, generalmente, la primera versión escribirá una sola línea de una sola vez, mientras que la segunda versión puede dividirse mediante escrituras de otros subprocesos. A menudo me encuentro escribiendo std::cout << "hello\n" << std::flush para evitar esto.

    – chispas

    22 de junio de 2011 a las 23:15

  • Qué pasa std::cout << "Hello" << "\n";?

    – byxor

    22 de febrero de 2018 a las 20:39

  • @byxor Casi lo mismo, excepto el lavado del búfer como se describe en otras respuestas. De todos modos, es redundante cuando puede fusionar los dos literales de cadena en uno.

    – iBug

    19 de abril de 2018 a las 6:44

  • Bueno, si la cadena que se va a imprimir no es un literal, entonces las llamadas a la << sería 2 en el caso a también, por lo que no reclamaría la necesidad de uno o dos << (o dos llamadas de función en general) ser una diferencia entre \n y endl.

    – Enlico

    22 de noviembre de 2018 a las 14:30


  • Lol no, esa no es la razón por la que uso \n.

    – Carlos Wood

    27 de febrero de 2019 a las 10:27

1647631393 493 stdendl frente a n
Ferruccio

Ambos escribirán los caracteres de fin de línea apropiados. Además de eso, endl hará que se confirme el búfer. Por lo general, no desea utilizar endl al realizar E/S de archivos porque las confirmaciones innecesarias pueden afectar el rendimiento.

  • Puede ser obvio, pero tiene un gran impacto en los programas con subprocesos donde, generalmente, la primera versión escribirá una sola línea de una sola vez, mientras que la segunda versión puede dividirse mediante escrituras de otros subprocesos. A menudo me encuentro escribiendo std::cout << "hello\n" << std::flush para evitar esto.

    – chispas

    22 de junio de 2011 a las 23:15

  • Qué pasa std::cout << "Hello" << "\n";?

    – byxor

    22 de febrero de 2018 a las 20:39

  • @byxor Casi lo mismo, excepto el lavado del búfer como se describe en otras respuestas. De todos modos, es redundante cuando puede fusionar los dos literales de cadena en uno.

    – iBug

    19 de abril de 2018 a las 6:44

  • Bueno, si la cadena que se va a imprimir no es un literal, entonces las llamadas a la << sería 2 en el caso a también, por lo que no reclamaría la necesidad de uno o dos << (o dos llamadas de función en general) ser una diferencia entre \n y endl.

    – Enlico

    22 de noviembre de 2018 a las 14:30


  • Lol no, esa no es la razón por la que uso \n.

    – Carlos Wood

    27 de febrero de 2019 a las 10:27

1647631393 287 stdendl frente a n
Özgür

No es gran cosa, pero endl no funcionará en impulso::lambda.

(cout<<_1<<endl)(3); //error

(cout<<_1<<"\n")(3); //OK , prints 3

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad