¿Usa un manipulador de flujo (endl) o un carácter de escape de nueva línea (\ n)?

12

No tengo un contexto específico en el que estoy haciendo la pregunta, pero mientras leía un libro para principiantes en C ++ noté el uso de un manipulador de flujo endl y un carácter de escape de nueva línea cuando se trata de un objeto de flujo.

El ejemplo es el siguiente:

cout << "Hello World" << endl;
cout << "Hello World\n";

Mis preguntas son:

  1. ¿Es más apropiado usar el manipulador de flujo (endl) en una situación determinada y un personaje de escape en una diferente?
  2. ¿Existen inconvenientes en cuanto a eficiencia al usar uno de los dos?
  3. ¿Son completamente intercambiables?
  4. Leí que una secuencia de escape se almacena en la memoria como un solo personaje. ¿Eso significa que es más apropiado usar endl si vas a consumir poca memoria?
  5. ¿El manipulador de flujo utiliza memoria de alguna manera, si es así, es más que la secuencia de escape?

Gracias, StackExchange Disculpas si publiqué esto en la sección incorrecta, pensé que contaba como estructuras de datos.

Nathan Taylor
fuente
2
endl también causa una descarga en algunas secuencias, '\ n' no lo hace.
James

Respuestas:

12

o << std::endl es equivalente al siguiente código:

o.put(o.widen('\n'));
o.flush();

En otras palabras, solo debe usar std::endlcuando necesita vaciar la transmisión. Por ejemplo:

  • Está a punto de realizar una operación que requiere mucho tiempo y desea asegurarse de mostrar un mensaje antes de hacerlo.
  • Otro proceso está esperando su salida.
  • Si se está ejecutando más de un subproceso o proceso, es posible que deba vaciar la salida para que el resultado de cada subproceso o proceso se muestre correctamente. (De lo contrario, puede obtener bloques de salida aparentemente aleatorios intercalados a intervalos incómodos).

Si no necesita vaciar el flujo, use en \nlugar de std::endl. Las llamadas adicionales a flushpueden afectar el rendimiento (a veces significativamente).

Para más detalles, visite cppreference.com .

Con respecto al uso de la memoria: Preocuparse por el \nversus std::endles casi seguro una microoptimización innecesaria, pero en general, esperaría \ntener menos memoria. \nes solo un byte más al final de un literal de cadena, mientras que la escritura std::endles traducida por el compilador a (probablemente en línea) llamadas a funciones a puty flush.

Las diferencias específicas de plataforma en los finales de línea (Windows \r\nversus Linux y OS X \n) se manejan en un nivel más bajo que std::endly \n:

  • Si se abre una secuencia en modo de texto, si escribe \n, la traduce automáticamente al final de línea apropiado para la plataforma específica. Si lee un final de línea específico de la plataforma, la transmisión se traduce automáticamente a \n.
  • Si se abre una secuencia en modo binario, entonces pasan cualquier final de línea literalmente, y depende de usted.
  • Por std::couty std::cinen particular, se tratan como si fueran en modo texto.
Josh Kelley
fuente
1

1) Para portabilidad, uso endl. Las nuevas líneas de Windows son \r\n, Linux \ny Mac \r. Editar: según los comentarios, las terminaciones específicas del sistema de línea se manejan en un nivel inferior.

2) endllava la corriente, "\n"no lo hace.

3) Depende de la portabilidad.

En cuanto al uso de memoria, puede minimizarlo volcando a otro almacenamiento con la mayor frecuencia posible endl. Sin embargo, disminuirá el rendimiento.

Editar: aclara algunos errores.

Kent
fuente
2
Mac ha estado basado en Unix desde OS X y, por lo tanto, también está \nen cualquier máquina moderna.
77
Lo siento, pero esto es incorrecto. endly \nson equivalentes con respecto a las terminaciones de línea específicas de la plataforma; Las diferencias de plataforma se manejan en un nivel inferior.
Josh Kelley
2
Tu primer punto está mal. endl () envía '\ n' al flujo (además de vaciarlo). El carácter '\ n' se convierte a la plataforma específica End of line sequence(asumiendo el modo de texto). El End of line sequencese convierte de nuevo a '\ n` cuando se lee desde un archivo. El punto 3) es dudoso. Y el último párrafo está nuevamente equivocado: el vaciado no le ahorrará espacio y el vaciado más de lo necesario ralentizará su código (el objetivo del búfer es mejorar la eficiencia de escritura en un dispositivo lento).
Martin York