Question C ++: "std :: endl" vs "\ n"


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

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

... donc j'ai toujours fait ça aussi. Mais j'ai vu beaucoup de code de développeurs travaillant comme ça:

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

Y a-t-il une raison technique de préférer l'un à l'autre ou est-ce juste une question de style de codage?


433
2017-10-17 21:25


origine


Réponses:


Les différents caractères de fin de ligne n'ont pas d'importance, en supposant que le fichier est ouvert en mode texte, ce qui est ce que vous obtenez à moins que vous demandiez binaire. Le programme compilé écrira la bonne chose pour le système compilé.

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


371
2017-10-17 21:56



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

std::cout << std::endl;

est équivalent à

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

Alors,

  • Utilisation std::endl Si vous voulez forcer un rinçage immédiat à la sortie.
  • Utilisation \n si vous êtes inquiet au sujet de la performance (ce qui n'est probablement pas le cas si vous utilisez le << opérateur).

j'utilise \n sur la plupart des lignes.
Ensuite, utilisez std::endl à la fin d'un paragraphe (mais c'est juste une habitude et pas habituellement nécessaire).

Contrairement à d'autres revendications, \n le caractère est mappé sur la bonne séquence de fin de ligne de la plate-forme uniquement si le flux va dans un fichier (std::cin et std::cout être spécial mais toujours des fichiers (ou des fichiers)).


183
2017-10-17 22:43



Il pourrait y avoir des problèmes de performance, std::endl force une vidange du flux de sortie.


39
2017-10-17 21:28



Il y a un autre appel de fonction implicite là-bas si vous allez utiliser std::endl

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

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


23
2017-11-17 22:29



Je me suis rappelé avoir lu à ce sujet dans la norme, alors voici:

Voir la norme C11 qui définit comment les flux standards se comportent, comme les programmes C ++ interfacent le CRT, la norme C11 devrait régir la politique de vidage ici.

ISO / CEI 9899: 201x

7.21.3 §7

Au démarrage du programme, trois flux de texte sont prédéfinis et n'ont pas besoin d'être ouverts explicitement   - entrée standard (pour lire l'entrée conventionnelle), sortie standard (pour écrire   sortie conventionnelle), et erreur standard (pour écrire une 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 la norme   les flux de sortie sont entièrement tamponnés si et seulement si le flux peut être déterminé à ne pas se référer   à un appareil interactif.

7.21.3 §3

Lorsqu'un flux n'est pas tamponné, les caractères sont destinés à apparaître depuis la source ou au   destination dès que possible. Sinon, les caractères peuvent être accumulés et   transmis vers ou depuis l'environnement hôte en tant que bloc. Quand un flux est entièrement tamponné,   les caractères sont destinés à être transmis vers ou depuis l'environnement hôte en tant que bloc lorsque   un tampon est rempli. Lorsqu'un flux est mis en tampon de ligne, les caractères sont destinés à être   transmis vers ou depuis l'environnement hôte en tant que 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, lorsque l'entrée est demandée sur un flux non tamponné, ou   lorsque l'entrée est demandée sur un flux en ligne tamponné qui nécessite la transmission de   caractères de l'environnement hôte. Le support de ces caractéristiques est   implémentation-defined, et peuvent être affectés via les fonctions setbuf et setvbuf.

Cela signifie que std::cout et std::cin sont entièrement tamponnés si et seulement si ils font référence à un périphérique non interactif. En d'autres termes, si stdout est attaché à un terminal, il n'y a pas de différence de comportement.

Toutefois, si std::cout.sync_with_stdio(false) est appelé, alors '\n' ne provoquera pas de vidange, même pour les appareils interactifs. Autrement '\n' est équivalent à std::endl à moins de rediriger vers des fichiers: ref c ++ sur std :: endl.


21
2017-08-29 13:58



Ils écriront tous deux le ou les caractères de fin de ligne appropriés. En plus de cela, endl provoquera la validation du tampon. Vous ne voulez généralement pas utiliser endl lorsque vous faites des E / S de fichiers, car les commits inutiles peuvent avoir un impact sur les performances.


17
2017-10-17 21:33



Pas un gros problème, mais endl ne fonctionnera pas dans boost :: lambda.

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

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

11
2018-02-22 01:57



Si vous utilisez Qt et endl, vous pourriez accidentellement utiliser le mauvais endl, est arrivé à moi 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, puisque j'aurais dû écrire std::endl, mais si vous utilisez endl, qt et using namespace std; cela dépend de l'ordre des fichiers include si le bon endl sera utilisé.*

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

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

* EDIT2: C ++ choisira le bon endl si tu as un using pour std::cout ou l'espace de noms std, depuis std::endl est dans le même espace de nom que std::cout, Le mécanisme ADL de C ++ choisira std::endl.


9
2018-02-17 01:21