"std:: endl" vs " \n"

Wiele książek C++ zawiera przykładowy kod, taki jak ten...

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

...więc zawsze to robiłem. Ale widziałem dużo kodu od pracujących programistów, takich jak ten:

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

Czy Jest jakiś techniczny powód, aby preferować jedno nad drugim, czy jest to tylko kwestia stylu kodowania?

Author: Asteroids With Wings, 2008-10-17

12 answers

Różne znaki końca linii nie mają znaczenia, zakładając, że plik jest otwarty w trybie tekstowym, co jest tym, co dostajesz, chyba że poprosisz o binarne. Skompilowany program napisze poprawną rzecz dla skompilowanego systemu.

Jedyną różnicą jest to, że std::endl spłukuje bufor wyjściowy, a '\n' nie. jeśli nie chcesz, aby bufor był często spłukiwany, użyj '\n'. Jeśli tak (na przykład, jeśli chcesz uzyskać wszystkie dane wyjściowe, a program jest niestabilny), użyj std::endl.

 492
Author: David Thornley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-08 22:16:17

Różnicę można zilustrować następująco:

std::cout << std::endl;

Jest równoważne

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

Więc,

  • Użyj std::endl, Jeśli chcesz wymusić natychmiastowe spłukanie na wyjściu.
  • Użyj \n, Jeśli martwisz się o wydajność (co prawdopodobnie nie ma miejsca, jeśli używasz operatora <<).

Używam \n na większości linii.
Następnie użyj std::endl na końcu akapitu (ale to tylko nawyk, a nie Zwykle konieczne).

W przeciwieństwie do innych twierdzeń, znak \n jest mapowany do właściwego końca linii linii tylko wtedy, gdy strumień trafia do pliku (std::cin i std::cout są specjalne, ale nadal pliki (lub podobne do plików)).

 264
Author: Martin York,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-19 17:40:45

Mogą wystąpić problemy z wydajnością, std::endl wymusza spłukanie strumienia wyjściowego.

 41
Author: Martin Beckett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-15 04:33:44

Przypomniałem sobie czytanie o tym w standardzie, więc oto idzie:

Patrz standard C11, który określa, jak zachowują się standardowe strumienie, ponieważ programy C++ interfejsu CRT, standard C11 powinien regulować politykę flushing tutaj.

ISO / IEC 9899: 201x

7.21.3 §7

Podczas uruchamiania programu trzy strumienie tekstowe są predefiniowane i nie muszą być jawnie otwierane - standardowe wejście (do odczytu konwencjonalnego wejścia), standardowe wyjście (do zapisu konwencjonalne wyjście), oraz błąd standardowy (do zapisu wyjścia diagnostycznego). Jak początkowo otwarty, standardowy strumień błędów nie jest w pełni buforowany; standardowe wejście i standardowe strumienie wyjściowe są w pełni buforowane wtedy i tylko wtedy, gdy można określić, że strumień nie odnosi się do urządzenia interaktywnego.

7.21.3 §3

Gdy strumień nie jest buforowany, znaki mają pojawić się ze źródła lub na miejsce jak najszybciej. W przeciwnym razie można gromadzić znaki i przesyłane do lub ze środowiska hosta jako blok. Gdy strumień jest w pełni buforowany, znaki mają być przesyłane do lub ze środowiska hosta jako blok, gdy bufor jest wypełniony. Gdy strumień jest buforowany, znaki mają być przesyłane do lub ze środowiska hosta jako blok, gdy znak nowej linii jest / align = "left" / Ponadto znaki mają być przekazywane jako blok do hosta środowiska, gdy bufor jest wypełniony, gdy wejście jest żądany na strumieniu niebuforowanym, lub gdy dane wejściowe są wymagane w strumieniu buforowanym liniowym, który wymaga transmisji postaci ze środowiska hosta. Wsparcie dla tych cech jest implementacja-zdefiniowana i może mieć wpływ za pomocą funkcji setbuf i setvbuf.

Oznacza to, że std::cout i std::cin są w pełni buforowane wtedy i tylko wtedy, gdy odnoszą się do urządzenia nieinteraktywnego. Innymi słowy, jeśli stdout jest dołączony do terminala, to nie ma różnica w zachowaniu.

Jeśli jednak wywołane jest std::cout.sync_with_stdio(false), to '\n' nie spowoduje spłukania nawet urządzeń interaktywnych. W przeciwnym razie {[3] } jest równoważne std::endl, chyba że przekierowanie do plików: C++ ref na std:: endl.

 30
Author: Emily L.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-15 18:33:25

Jest tam inne wywołanie funkcji, jeśli zamierzasz użyć std::endl

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

A) wywołuje operatora << raz.
b) połączenia operatora << dwa razy.

 30
Author: Nathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-12 07:05:21

Oba będą pisać odpowiednie znaki końca linii. Oprócz tego endl spowoduje zaangażowanie bufora. Zwykle nie chcesz używać endl podczas wykonywania operacji wejścia/wyjścia plików, ponieważ niepotrzebne commity mogą mieć wpływ na wydajność.

 19
Author: Ferruccio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-17 21:33:32

Nic wielkiego, ale endl nie zadziała w boost:: lambda.

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

(cout<<_1<<"\n")(3); //OK , prints 3
 12
Author: Özgür,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-22 01:57:21

Jeśli używasz Qt i endl, możesz przypadkowo użyć niepoprawnego endl, co daje bardzo zaskakujące rezultaty. Zobacz poniższy fragment kodu:

#include <iostream>
#include <QtCore/QtCore> 
#include <QtGui/QtGui>

// notice that there is no "using namespace std;"
int main(int argc, char** argv)
{
    QApplication qapp(argc,argv);
    QMainWindow mw;
    mw.show();
    std::cout << "Finished Execution!" << endl;
    // This prints something similar to: "Finished Execution!67006AB4"
    return qapp.exec();
}

Zauważ, że napisałem endl zamiast std::endl (co byłoby poprawne) i najwyraźniej istnieje endl funkcja zdefiniowana w qtextstream.h (który jest częścią QtCore).

Użycie "\n" zamiast endl całkowicie pomija potencjalne problemy z przestrzenią nazw. Jest to również dobry przykład, dlaczego umieszczanie symboli do globalnej przestrzeni nazw (tak jak Domyślnie robi to Qt) jest złym pomysłem.

 10
Author: smerlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-13 20:32:48

Zawsze miałem zwyczaj używania std:: endl, ponieważ łatwo mi to dostrzec.

 3
Author: Zee JollyRoger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-17 21:53:29

Manipulator std::endl jest odpowiednikiem '\n'. Ale zawsze spłukuje strumień.

std::cout << "Test line" << std::endl; // with flush
std::cout << "Test line\n"; // no flush
 2
Author: Newbyte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-21 16:14:37

Jeśli zamierzasz uruchomić swój program na czymkolwiek innym niż własny laptop, nigdy nie używaj instrukcji endl. Zwłaszcza jeśli piszesz dużo krótkich linii lub jak często widziałem pojedyncze znaki do pliku. Użycie endl jest znane do zabijania sieciowych systemów plików, takich jak NFS.

 1
Author: John Damm Sørensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-28 08:29:30

Z referencją jest to manipulator wejścia/wyjścia tylko dla wyjścia.

std::endl wstawia znak nowej linii do sekwencji wyjściowej systemu operacyjnego i spłukuje go tak, jakby wywołując os.put(os.widen('\n')), a następnie os.flush().

Kiedy stosować:

Ten manipulator może być użyty do wytworzenia linii wyjścia natychmiast ,

Np.

Podczas wyświetlania wyników z długotrwałego procesu, rejestrowania aktywności wielu wątków lub rejestrowania aktywność programu, który może nieoczekiwanie ulec awarii.

Również

Jawny flush std::cout jest również konieczny przed wywołaniem STD::system, jeśli proces wywołany wykonuje dowolne screen I/o. w większości innych typowych interaktywnych scenariuszy We/Wy, STD::endl jest zbędny, gdy jest używany z std::cout, ponieważ każde wejście ze std::cin, wyjście ze STD::cerr lub zakończenie programu wymusza wywołanie std:: cout.flush (). Użycie std:: endl zamiast '\n', zachęcane przez niektórych źródła, może znacznie obniżyć wydajność wyjściową.

 0
Author: Kaleem Ullah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-27 11:58:16