"n" ou "n " ou std::endl à std::cout? [dupliquer]

cette question a déjà une réponse ici:

  • C++: "std:: endl" vs "n " 11 réponses

il y a de nombreuses années maintenant que j'ai cessé d'utiliser std::endl pour terminer les lignes en écrivant à std::cout , et a commencé à utiliser "n" à la place.

Mais maintenant je commence à voir plus de morceaux de code en utilisant 'n' à la place, et je commence à me demander ce qui pourrait être mieux.

outre l'évidence que l'un est une chaîne, et l'autre un caractère, est-il un avantage à utiliser ce:

std::cout << variable << 'n';

au Cours de cette:

std::cout << variable << "n";

ajout tardif:

quand j'ai posé cette question j'ai semblé penser que newline 'n' vidé la mémoire tampon. Maintenant je sais qu'il dépend .

par défaut std::cin est lié à l'ancien c stdin FILE* stream, et std::cout est lié à stdout . Le flush sur newline vient de ce montage. Par défaut, stdout , s'il est connecté à un terminal, est doté d'un tampon de ligne. Cela signifie qu'une nouvelle ligne va rincer ses tampons. Ainsi, lors de l'impression d'une nouvelle ligne en utilisant std::cout , cela conduira à stdout être rincé.

si stdout n'est pas connecté à un terminal (par exemple, la sortie a été redirigée ou est acheminée par canalisation), ou si le lien entre std::cout et stdout est rompu, alors les nouvelles lignes ne seront pas rincer quoi que ce soit.

85
demandé sur Some programmer dude 2011-11-29 16:55:07

6 réponses

en fait, '\n' devrait être la valeur par défaut. À moins que vous ne vouliez aussi purger explicitement le flux (et quand et pourquoi voudriez-vous faire cela?), il n'est pas nécessaire d'utiliser std::endl . 1

Bien sûr, de nombreux livres et tutoriels utilisent std::endl comme valeur par défaut. Cela est regrettable et pourrait conduire à graves bogues de performance .

je suppose qu'il y a peu de différence entre en utilisant '\n' ou en utilisant "\n" , mais ce dernier est un tableau de (deux) caractères, qui doit être imprimé caractère par caractère, pour lequel une boucle doit être mis en place, ce qui est plus complexe que la sortie d'un seul caractère. Bien sûr, quand vous faites IO cela importe rarement, mais si dans le doute, quand vous voulez sortir un caractère littéral, sortir un caractère littéral, plutôt qu'une chaîne entière littérale.

Un bel effet de le faire, c'est que vous communiquez dans votre code que vous prévu pour produire un seul caractère, et pas juste accidentellement fait cela.


1 notez que std::cout est lié à std::cin par défaut, ce qui conduit à std::cout être rincé avant toute opération d'entrée, de sorte que n'importe quel invite sera imprimé avant que l'utilisateur doit entrer quelque chose.

95
répondu sbi 2011-11-29 13:17:08

Ils font des choses différentes. "\n" produit une nouvelle ligne (dans la représentation appropriée spécifique à la plate-forme, de sorte qu'il génère un "\r\n" sur Windows), mais std::endl fait la même et chasse le flux . Habituellement, vous n'avez pas besoin de vider le flux immédiatement et il vous coûtera juste la performance, donc pour la plupart, il n'y a pas de raison d'utiliser std::endl .

14
répondu jalf 2011-11-29 13:06:15

Il n'y a pas la meilleure. Vous utilisez ce dont vous avez besoin:

  • '\n' - pour terminer la ligne
  • "une chaîne de caractères\n" - la fin de la ligne après une chaîne de caractères
  • std::endl - pour terminer la ligne et rincer le ruisseau
13
répondu BЈовић 2011-11-29 13:00:30

Edit: j'ai mal formulé ma réponse, ce qui peut avoir conduit les gens à croire que je pensais "\n" réellement imprimé un caractère nul. C'est évidemment faux :)

Edit 2: Après avoir regardé une référence C++, char s sont passés par référence de toute façon, il n'y a donc aucune différence. La seule différence est que le cstring devra être recherché pour un signe de séparation. ce qui suit n'est pas correct en raison de ce fait.

'\n' serait toujours un peu plus efficace que "\n" , car ce dernier contient également un caractère nul à la fin, ce qui signifie que vous envoyez un char* à operator<<() (généralement 4 octets sur un système 32 bits) par opposition à un seul octet pour un char .

dans la pratique, ceci est à la limite de la non-pertinence. Personnellement, je suis la convention dont Vladimir a parlé.*

3
répondu Chris Parton 2011-11-29 22:21:48

std::endl vide le flux. Lorsque vous voulez que cela se produise-par exemple parce que vous vous attendez à ce que votre sortie soit rendue visible à l'utilisateur en temps opportun-vous devez utiliser std::endl au lieu d'écrire '\n' au flux (que ce soit comme un caractère isolé ou une partie d'une chaîne de caractères).

parfois, vous pouvez vous en tirer sans purger explicitement le flux vous-même; par exemple dans un environnement linux, si cout est synchronisé avec STDOUT (c'est la valeur par défaut) et est écrit à un terminal, puis par défaut, le flux sera Line buffered et sera automatiquement flush chaque fois que vous écrivez une nouvelle ligne.

cependant, il est risqué de se fier à ce comportement. par exemple, dans le même environnement linux, si vous décidez d'exécuter votre programme avec stdout redirigé vers un fichier ou redirigé vers un autre processus, alors par défaut, le flux sera bloc tamponné plutôt.

de même, si vous décidez plus tard de désactiver la synchronisation avec stdio (par exemple pour l'efficacité), alors les implémentations auront tendance à utiliser les mécanismes de mise en mémoire tampon de iostream , qui n'ont pas de mode de mise en mémoire tampon de ligne.

j'ai vu beaucoup de perte de productivité due à cette erreur; si la sortie doit être visible quand il est écrit, alors vous devriez utiliser std::endl explicitement (ou utiliser std::flush ou std::ostream::flush , mais je trouve habituellement std::endl plus pratique), ou faire quelque chose d'autre qui assure le rinçage se produit assez souvent, comme la configuration de stdout pour être amortie par la ligne (en supposant que c'est suffisant).

3
répondu Hurkyl 2015-11-18 10:23:52
  • std::cout << variable << std::endl;

    std::endl sortie une nouvelle ligne, mais il chasse également le flux de sortie. En d'autres termes, même effet que

    std::cout << variable << '\n'; // output newline
    std::cout.flush();      // then flush 
    
  • std::cout << variable << '\n';

    '\n' sortie une nouvelle ligne pour un char, donc ostream& operator<< (ostream& os, char c); sera utilisée.

  • std::cout << variable << "\n";

    "\n" est un const char[2] , donc ostream& operator<< (ostream& os, const char* s); sera utilisé. Nous pouvons imaginer, cette fonction contiendra une boucle, nous pourrions soutenir est exagéré de juste imprimer une nouvelle ligne.

3
répondu zangw 2016-01-15 07:16:33