Vous utilisez un manipulateur de flux (endl) ou un caractère d'échappement de nouvelle ligne (\ n)?

12

Je n'ai pas de contexte spécifique dans lequel je pose la question, mais pendant que je lisais un livre pour débutants sur C ++, j'ai remarqué l'utilisation à la fois d'un manipulateur de flux endl et d'un caractère d'échappement newline lors du traitement d'un objet stream.

L'exmaple est le suivant:

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

Mes questions sont:

  1. Est-il plus approprié d'utiliser le manipulateur de flux (endl) dans une certaine situation et un caractère d'échappement dans une autre?
  2. Y a-t-il des inconvénients en termes d'efficacité à utiliser l'un des deux?
  3. Sont-ils complètement interchangeables?
  4. J'ai lu qu'une séquence d'échappement est stockée en mémoire comme un seul caractère. Cela signifie-t-il qu'il est plus approprié d'utiliser endl si vous optez pour une faible consommation de mémoire?
  5. Le manipulateur de flux utilise-t-il la mémoire de quelque façon que ce soit, si c'est plus que la séquence d'échappement?

Merci, StackExchange Excuses si j'ai posté ceci dans la mauvaise section, je pensais que cela comptait comme des structures de données.

Nathan Taylor
la source
2
endl provoque également un vidage sur certains flux, '\ n' non.
James

Réponses:

12

o << std::endl est équivalent au code suivant:

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

En d'autres termes, vous ne devez l'utiliser que std::endllorsque vous devez vider le flux. Par exemple:

  • Vous êtes sur le point d'effectuer une opération longue et souhaitez vous assurer d'afficher un message avant de le faire.
  • Un autre processus attend votre sortie.
  • Si plusieurs threads ou processus sont en cours d'exécution, vous devrez peut-être vider la sortie afin que la sortie de chaque thread ou processus s'affiche correctement. (Sinon, vous pouvez obtenir des blocs de sortie apparemment aléatoires entrelacés à des intervalles maladroits.)

Si vous n'avez pas besoin de vider le flux, utilisez \nplutôt au lieu de std::endl. Les appels supplémentaires à flushpeuvent nuire aux performances (parfois de manière significative).

Pour plus de détails, voir cppreference.com .

En ce qui concerne l'utilisation de la mémoire: s'inquiéter de \nversus std::endlest presque certainement une micro-optimisation inutile, mais en général, je m'attends \nà consommer moins de mémoire. \nn'est qu'un octet de plus à la fin d'un littéral de chaîne, tandis que l'écriture std::endlest traduite par le compilateur en appels de fonction (probablement en ligne) à putet flush.

Les différences spécifiques à la plate-forme dans les fins de ligne (Windows \r\npar rapport à Linux et OS X \n) sont traitées à un niveau inférieur à std::endlet \n:

  • Si un flux est ouvert en mode texte, alors si vous écrivez \n, il le traduit automatiquement en la fin de ligne spécifique à la plate-forme appropriée. Si vous lisez une fin de ligne spécifique à la plate-forme, le flux la traduit automatiquement \n.
  • Si un flux est ouvert en mode binaire, ils passent toutes les fins de ligne par mot à mot, et c'est à vous de décider.
  • Pour std::coutet std::cinen particulier, ils sont traités comme s'ils étaient en mode texte.
Josh Kelley
la source
1

1) Pour la portabilité, utilisez endl. Les nouveautés Windows sont \r\n, Linux \net Mac \r. Modifier: selon les commentaires, les terminaisons spécifiques au système de ligne sont traitées à un niveau inférieur.

2) endlrince le flux, "\n"non.

3) Dépend de la portabilité.

En ce qui concerne l'utilisation de la mémoire, vous pouvez la minimiser en vidant vers un autre stockage aussi souvent que possible avec endl. Cependant, cela diminuera les performances.

Edit: Éliminez certaines erreurs.

Kent
la source
2
Mac est basé sur Unix depuis OS X et est donc également \nsur n'importe quelle machine moderne.
7
Désolé, mais c'est incorrect. endlet \nsont équivalents en ce qui concerne les fins de ligne spécifiques à la plate-forme; les différences de plate-forme sont traitées à un niveau inférieur.
Josh Kelley
2
Votre premier point est faux. endl () envoie '\ n' au flux (en plus de le vider). Le caractère '\ n' est converti en spécifique à la plateforme End of line sequence(en supposant le mode texte). Le End of line sequenceest reconverti en «\ n» lors de la lecture d'un fichier. Le point 3) est douteux. Et le dernier paragraphe est à nouveau faux: le rinçage ne vous fera pas économiser d'espace et le rinçage plus que nécessaire ralentira votre code (le but du tampon est d'améliorer l'efficacité d'écriture sur un périphérique lent).
Martin York