С++: "std:: endl" vs "\n"

Многие книги на С++ содержат пример кода вроде этого...

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

... поэтому я всегда это делал. Но я видел много кода от таких разработчиков, как это:

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

Есть ли техническая причина, чтобы предпочесть один над другим, или это просто вопрос стиля кодирования?

Ответ 1

Различные символы окончания строки не имеют значения, предполагая, что файл открыт в текстовом режиме, и это то, что вы получаете, если не запрашиваете двоичный файл. Скомпилированная программа выведет правильную вещь для скомпилированной системы.

Единственное различие заключается в том, что std::endl удаляет выходной буфер, а '\n' - нет. Если вы не хотите, чтобы буфер часто промывался, используйте '\n'. Если вы это сделаете (например, если вы хотите получить весь вывод, а программа нестабильна), используйте std::endl.

Ответ 2

Разницу можно проиллюстрировать следующим образом:

std::cout << std::endl;

эквивалентно

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

Итак,

  • Используйте std::endl Если вы хотите принудительно выполнить немедленный вывод на выход.
  • Используйте \n, если вас беспокоит производительность (что, вероятно, не так, если вы используете оператор <<).

Я использую \n для большинства строк.
Затем используйте std::endl в конце абзаца (но это просто привычка и обычно не требуется).

В отличие от других утверждений символ \n отображается на правильный конец строки последовательности строк, только если поток переходит к файлу (std::cin и std::cout являются специальными, но все же файлами (или файловыми )).

Ответ 3

Возможны проблемы с производительностью, std::endl заставляет поток потока вывода.

Ответ 4

Я вспомнил, что читал об этом в стандарте, так что вот:

См. стандарт C11, который определяет, как ведут себя стандартные потоки, поскольку программы на С++ взаимодействуют с CRT, стандарт C11 должен регулировать политику очистки.

ISO/IEC 9899: 201x

7.21.3 §7

При запуске программы три текстовых потока предопределены и их явно не нужно открывать - стандартный вход (для чтения обычного входа), стандартный выход (для записи традиционный выход) и стандартная ошибка (для записи диагностического вывода). Как первоначально открыт, стандартный поток ошибок не полностью буферизирован; стандартный ввод и стандартный выходные потоки полностью буферизуются тогда и только тогда, когда поток можно определить, чтобы не ссылаться к интерактивному устройству.

7.21.3 §3

Когда поток небуферизирован, символы должны появляться из источника или на назначения как можно скорее. В противном случае символы могут накапливаться и передается в или из среды хоста в виде блока. Когда поток полностью буферизуется, символы предназначены для передачи в или из среды хоста в виде блока, когда буфер заполняется. Когда поток буферизируется по строке, символы предназначены для передается в или из среды хоста в виде блока, когда символ новой строки встречается. Кроме того, символы предназначены для передачи в виде блока хосту среда, когда буфер заполняется, когда запрос запрашивается в небуферизованном потоке или когда запрос запрашивается в потоке с линейной буферизацией, который требует передачи символов из среды хоста. Поддержка этих характеристик определяемые реализацией, и могут быть затронуты с помощью функций setbuf и setvbuf.

Это означает, что std::cout и std::cin полностью буферизированы , если и только если, они относятся к неинтерактивному устройству. Другими словами, если stdout подключен к терминалу, то нет никакой разницы в поведении.

Однако, если вызывается std::cout.sync_with_stdio(false), то '\n' не приведет к потоку даже для интерактивных устройств. В противном случае '\n' эквивалентно std::endl, если не передать сообщения в файлы: С++ ref на std:: endl.

Ответ 5

Там есть другой вызов функции, если вы собираетесь использовать std::endl

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

a) вызывает оператор << один раз.
b) дважды вызывает оператор <<.

Ответ 6

Они оба будут писать соответствующий символ конца строки. В дополнение к этому endl приведет к блокировке буфера. Обычно вы не хотите использовать endl при выполнении ввода-вывода файлов, поскольку ненужные коммиты могут влиять на производительность.

Ответ 8

Если вы используете Qt и endl, вы случайно можете использовать неправильный endl, со мной случилось сегодня, и я был как..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();
}

Конечно, это была моя ошибка, так как я должен был написать std::endl, , но если вы используете endl, qt и using namespace std;, это зависит от порядка включенных файлов, если правильный endl будет использоваться. *

Конечно, вы могли бы перекомпилировать Qt для использования пространства имен, поэтому вы получите ошибку компиляции для приведенного выше примера.

EDIT: Забыл отметить, что Qt endl объявлен в "qtextstream.h", который является частью QtCore

* EDIT2: С++ выберет правильный endl, если у вас есть using для std::cout или пространства имен std, так как std::endl находится в том же пространстве имен, что и std::cout, механизм ADL С++ будет выберите std::endl.

Ответ 9

У меня всегда была привычка просто использовать std:: endl, потому что мне легко видеть.

Ответ 10

С reference Это манипулятор ввода-вывода только для вывода.

std::endl Вставляет символ новой строки в выходную последовательность os и сбрасывает ее, как если бы она вызывала os.put(os.widen('\n')), а затем os.flush().

Когда использовать:

Этот манипулятор может использоваться для немедленного создания строки вывода,

например

при отображении вывода из долговременного процесса, регистрации активности нескольких потоков или активности ведения журнала программы, которая может неожиданно произойти сбой.

И

Явный поток std:: cout также необходим перед вызовом в std:: system, если порожденный процесс выполняет любой экран ввода-вывода. В большинстве других обычных интерактивных сценариев ввода-вывода std:: endl избыточен при использовании с std:: cout, потому что любой вход из std:: cin, вывод в std:: cerr или завершение программы заставляет вызов std:: cout.промывать(). Использование std:: endl вместо '\n', которое поощряется некоторыми источниками, может значительно ухудшить производительность вывода.

Ответ 11

Если вы намереваетесь запустить свою программу на чем-то другом, кроме вашего ноутбука, никогда не используйте оператор endl. Особенно, если вы пишете много коротких строк или, как я часто видел, отдельные символы в файле. Известно, что использование endl убивает сетевые файловые системы, такие как NFS.

Ответ 12

Манипулятор endl эквивалентен '\'. Но endl всегда сбрасывает поток.

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

Ответ 13

Если вы не заметили, endl походит на нажатие клавиши ENTER, а "\n" похоже на нажатие ENTER KEY + SPACE BAR.