С++: "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 при выполнении ввода-вывода файлов, поскольку ненужные коммиты могут влиять на производительность.
Ответ 7
Неважно, но endl не будет работать в boost:: лямбда.
(cout<<_1<<endl)(3); //error
(cout<<_1<<"\n")(3); //OK , prints 3
Ответ 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.