Многие книги на С++ содержат пример кода вроде этого...
std::cout << "Test line" << std::endl;
... поэтому я всегда это делал. Но я видел много кода от таких разработчиков, как это:
std::cout << "Test line\n";
Есть ли техническая причина, чтобы предпочесть один над другим, или это просто вопрос стиля кодирования?
Различные символы окончания строки не имеют значения, предполагая, что файл открыт в текстовом режиме, и это то, что вы получаете, если не запрашиваете двоичный файл. Скомпилированная программа выведет правильную вещь для скомпилированной системы.
Единственное различие заключается в том, что std::endl
удаляет выходной буфер, а '\n'
- нет. Если вы не хотите, чтобы буфер часто промывался, используйте '\n'
. Если вы это сделаете (например, если вы хотите получить весь вывод, а программа нестабильна), используйте std::endl
.
::std::cerr
вместо ::std::cout
поскольку он небуферизован и сбрасывается при каждой операции вывода.
Разницу можно проиллюстрировать следующим образом:
std::cout << std::endl;
эквивалентно
std::cout << '\n' << std::flush;
Итак,
std::endl
Если вы хотите принудительно выполнить немедленный вывод на выход.\n
, если вас беспокоит производительность (что, вероятно, не так, если вы используете оператор <<
).Я использую \n
для большинства строк.
Затем используйте std::endl
в конце абзаца (но это просто привычка и обычно не требуется).
В отличие от других утверждений символ \n
отображается на правильный конец строки последовательности строк, только если поток переходит к файлу (std::cin
и std::cout
являются специальными, но все же файлами (или файловыми )).
cout
привязан к cin
, что означает, что если вы читаете ввод из cin
, cout
будет сброшен первым. Но если вы хотите отобразить индикатор выполнения или что-то без чтения из cin
, тогда, конечно, очистка полезна.
operator<<
не работает, или какую альтернативу использовать для производительности? Пожалуйста, укажите мне некоторые материалы, чтобы понять это дальше.
Возможны проблемы с производительностью, std::endl
заставляет поток потока вывода.
Я вспомнил, что читал об этом в стандарте, так что вот:
См. стандарт 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.
Там есть другой вызов функции, если вы собираетесь использовать std::endl
a) std::cout << "Hello\n";
b) std::cout << "Hello" << std::endl;
a) вызывает оператор <<
один раз.
b) дважды вызывает оператор <<
.
std::cout << "Hello" << "\n";
?
Они оба будут писать соответствующий символ конца строки. В дополнение к этому endl приведет к блокировке буфера. Обычно вы не хотите использовать endl при выполнении ввода-вывода файлов, поскольку ненужные коммиты могут влиять на производительность.
Неважно, но endl не будет работать в boost:: лямбда.
(cout<<_1<<endl)(3); //error
(cout<<_1<<"\n")(3); //OK , prints 3
Если вы используете 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
.
using namespace std;
?? :-)
У меня всегда была привычка просто использовать std:: endl, потому что мне легко видеть.
С 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', которое поощряется некоторыми источниками, может значительно ухудшить производительность вывода.
Если вы намереваетесь запустить свою программу на чем-то другом, кроме вашего ноутбука, никогда не используйте оператор endl
. Особенно, если вы пишете много коротких строк или, как я часто видел, отдельные символы в файле. Известно, что использование endl
убивает сетевые файловые системы, такие как NFS.
Если вы не заметили, endl
походит на нажатие клавиши ENTER, а "\n"
похоже на нажатие ENTER KEY + SPACE BAR.