Question

De nombreux livres C ++ contiennent un exemple de code comme celui-ci ...

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

... donc je l'ai toujours fait aussi. Mais au lieu de cela, j'ai vu beaucoup de code de développeurs qui travaillent:

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

Existe-t-il une raison technique de préférer l’un l’autre, ou est-ce juste une question de style de codage?

Était-ce utile?

La solution

Les différents caractères de fin de ligne importent peu, en supposant que le fichier soit ouvert en mode texte, ce que vous obtiendrez à moins que vous ne demandiez du binaire. Le programme compilé écrira ce qui convient pour le système compilé.

La seule différence est que std :: endl vide le tampon de sortie, mais pas '\ n' . Si vous ne voulez pas que le tampon soit vidé fréquemment, utilisez '\ n' . Si vous le faites (par exemple, si vous souhaitez obtenir toutes les sorties et que le programme est instable), utilisez std :: endl .

Autres conseils

La différence peut être illustrée par ce qui suit:

std::cout << std::endl;

est équivalent à

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

Alors,

  • Utilisez std :: endl Si vous voulez forcer un vidage immédiat vers la sortie.
  • Utilisez \ n si vous êtes préoccupé par les performances (ce qui n'est probablement pas le cas si vous utilisez l'opérateur < < ).

J'utilise \ n sur la plupart des lignes.
Ensuite, utilisez std :: endl à la fin d'un paragraphe (mais ce n'est qu'une habitude et n'est généralement pas nécessaire).

Contrairement à d’autres affirmations, le caractère \ n est associé à la séquence de fin de ligne de la plate-forme correcte uniquement si le flux est dirigé vers un fichier ( std :: cin et std :: cout étant spécial mais toujours des fichiers (ou des fichiers similaires)).

Il peut y avoir des problèmes de performances, std :: endl force le vidage du flux de sortie.

Je me suis souvenu d'avoir lu à ce sujet dans la norme, alors voici:

Voir la norme C11 qui définit le comportement des flux standard, car les programmes C ++ interfacent le tube cathodique (CRT). La norme C11 doit donc régir la stratégie de vidage.

  

ISO / CEI 9899: 201x

     

7.21.3 & # 167; 7

     

Au démarrage du programme, trois flux de texte sont prédéfinis et n'ont pas besoin d'être ouverts explicitement   & # 8212; entrée standard (pour lire entrée conventionnelle), sortie standard (pour écriture)   sortie conventionnelle) et erreur standard (pour l’écriture de la sortie de diagnostic). Comme initialement   ouvert, le flux d'erreur standard n'est pas entièrement mis en mémoire tampon; l'entrée standard et standard   les flux de sortie sont entièrement mis en mémoire tampon si et seulement si le flux peut être déterminé de ne pas se référer   vers un appareil interactif.

     

7.21.3 & # 167; 3

     

Lorsqu’un flux n’est pas mis en tampon, les caractères doivent apparaître à partir de la source ou au début.   destination le plus tôt possible. Sinon, des caractères risquent d’être accumulés et   transmis à ou de l'environnement hôte en tant que bloc. Quand un flux est complètement tamponné,   caractères sont destinés à être transmis à ou de l'environnement hôte sous forme de bloc lorsque   un tampon est rempli. Lorsqu'un flux est mis en mémoire tampon, les caractères doivent être   transmis à ou de l'environnement hôte sous forme de bloc lorsqu'un caractère de nouvelle ligne est   rencontré. De plus, les caractères sont destinés à être transmis en bloc à l'hôte   environnement lorsqu'un tampon est rempli, lorsqu'une entrée est demandée sur un flux non tamponné, ou   lorsque l’entrée est demandée sur un flux de ligne mis en mémoire tampon qui nécessite la transmission de   personnages de l'environnement hôte. Le support de ces caractéristiques est   défini par la mise en œuvre, et peut être affecté via les fonctions setbuf et setvbuf.

Cela signifie que std :: cout et std :: cin sont entièrement mis en mémoire tampon si et seulement si ils font référence à un non appareil interactif. En d'autres termes, si stdout est attaché à un terminal, il n'y a pas de différence de comportement.

Cependant, si std :: cout.sync_with_stdio (false) est appelé, '\ n' ne provoquera pas de vidage, même pour les périphériques interactifs. Sinon, '\ n' équivaut à std :: endl sauf si la canalisation vers des fichiers: référence c ++ sur std :: endl .

Un autre appel de fonction est impliqué si vous voulez utiliser std :: endl

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

a) appelle l'opérateur < < une fois.
b) appelle deux fois l'opérateur < < .

Ils écriront tous les deux les caractères de fin de ligne appropriés. En plus de cela, endl entraînera la validation de la mémoire tampon. En règle générale, vous ne souhaitez pas utiliser endl lorsque vous effectuez des E / S sur un fichier, car les validations inutiles peuvent avoir un impact négatif sur les performances.

Pas très grave, mais endl ne fonctionnera pas in boost :: lambda .

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

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

Si vous utilisez Qt et endl, vous pourriez accidentellement utiliser le mauvais endl , m'est arrivé aujourd'hui et j'étais comme ..WTF ??

#include <iostream>
#include <QtCore/QtCore> 
#include <QtGui/QtGui>
//notice that i dont have a "using namespace std;"
int main(int argc, char** argv)
{
    QApplication qapp(argc,argv);
    QMainWindow mw;
    mw.show();
    std::cout << "Finished Execution !" << endl << "...";
    // Line above printed: "Finished Execution !67006AB4..."
    return qapp.exec();
}

Bien sûr, c'était mon erreur, car j'aurais dû écrire std :: endl , mais si vous utilisez endl , qt et en utilisant un espace de noms std; cela dépend de l'ordre des fichiers d'inclusion si le endl correct sera utilisé. *

Bien entendu, vous pouvez recompiler Qt pour utiliser un espace de noms. Vous obtenez donc une erreur de compilation pour l'exemple ci-dessus.

EDIT: Oublié de mentionner, le endl de Qt est déclaré dans "qtextstream.h". qui fait partie de QtCore

* EDIT2: C ++ choisira le endl correct si vous avez un utilisant pour std :: cout ou l'espace de noms std , puisque std :: endl se trouve dans le même espace de noms que std :: cout , le mécanisme ADL de C ++ sélectionne std :: endl .

J'ai toujours eu l'habitude d'utiliser std :: endl car c'est facile à voir pour moi.

Avec la référence , il s'agit d'une sortie uniquement Manipulateur E / S .

std :: endl Insère un caractère de nouvelle ligne dans la séquence en sortie et le vide comme s'il appelait os.put (os.widen ('\ n ')) suivi de os.flush () .

Quand utiliser:

Ce manipulateur peut être utilisé pour produire une ligne de sortie immédiatement ,

.

p. ex.

  

lors de l'affichage des résultats d'un processus de longue durée, de la journalisation de l'activité de plusieurs threads ou de la journalisation d'un programme susceptible de planter de manière inattendue.

Aussi

  

Un vidage explicite de std :: cout est également nécessaire avant un appel à std :: system, si le processus engendré effectue une opération d’écran d’écran. Dans la plupart des autres scénarios d’entrées / sorties interactives usuels, std :: endl est redondant lorsqu’il est utilisé avec std :: cout car toute entrée de std :: cin, la sortie vers std :: cerr ou la terminaison de programme force un appel vers std :: cout. .affleurer(). L'utilisation de std :: endl à la place de '\ n', encouragée par certaines sources, peut dégrader considérablement les performances de sortie.

Si vous avez l'intention d'exécuter votre programme sur autre chose que votre propre ordinateur portable, n'utilisez jamais l'instruction endl . Surtout si vous écrivez beaucoup de lignes courtes ou comme j'ai souvent vu des caractères uniques dans un fichier. L’utilisation de endl est connue pour tuer les systèmes de fichiers en réseau comme NFS.

Le manipulateur endl est équivalent à '\' . Mais endl vide toujours le flux.

std::cout << "Test line" << std::endl; // with flush
std::cout << "Test line\n"; // no flush

Si vous n'avez pas remarqué, endl revient à appuyer sur la touche Entrée tandis que "\ n", revient à appuyer sur la touche Entrée, barre d'espacement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top