В чем разница между cout, cerr, clog заголовка iostream в c++? Когда использовать какой из них?
Я пытался исследовать разницу между cout
,cerr
и clog
в интернете, но не смог найти точный ответ. Я до сих пор не ясно, когда использовать который. Может ли кто-нибудь объяснить мне, через простые программы и проиллюстрировать идеальную ситуацию, когда использовать какой?
посетил этот сайт что показывает небольшую программу на cerr
и clog
, но выход, полученный там, также может быть получен с помощью cout
. Итак, я в замешательстве точное использование каждого из них.
8 ответов:
stdout
иstderr
- это разные потоки, хотя по умолчанию они оба относятся к выходу консоли. Перенаправление (трубопроводы) одного из них (напримерprogram.exe >out.txt
) не повлияет на другие.как правило,
stdout
должен использоваться для фактического вывода программы, в то время как вся информация и сообщения об ошибках должны быть напечатаны вstderr
, Так что если пользователь перенаправляет вывод в файл, информационные сообщения выводятся на экран, а не в выходной файл.
как правило, вы используете
std::cout
для нормального вывода,std::cerr
по ошибки, иstd::clog
для "logging" (что может означать все, что вы хотите, чтобы это означало).главное отличие в том, что
std::cerr
не буферизуется, как два других.
в связи с
stdout
иstderr
,std::cout
соответствуетstdout
, аstd::cerr
иstd::clog
Как соответствуетstderr
(кромеstd::clog
буферизуется).
cerr не требует буфера, поэтому он быстрее, чем другие, и не использует память, которая cout использует, а потому что cout буферизируется, это более полезно в некоторых случаях. Итак:
- использовать cout для стандартного вывода.
- использовать cerr показать ошибки.
- использовать засорить для регистрации.
стандартный выходной поток (cout):
cout
является экземпляромostream
класса.cout
используется для получения вывода на стандартном устройстве вывода, которое обычно является экраном дисплея. Данные, необходимые для отображения на экране, вставляются в стандартный выходной поток (cout
) с помощью оператора вставки (<<
).Un-buffered standard error stream (cerr):
cerr
- это стандартный поток ошибок, который используется для вывода ошибки. Это также экземплярostream
класса. Какcerr
и небуферизованные модули поэтому он используется, когда нам нужно немедленно отобразить сообщение об ошибке. Он не имеет буфера для хранения сообщения об ошибке и отображения позже.Буферизованный стандартный поток ошибок (clog): это также экземпляр
ostream
класс, и используется для отображения ошибок, но в отличие отcerr
ошибка сначала вставляется в буфер и хранится в буфере пока она полностью не заполнена.читайте далее : basic-input-output-c
разница этих 3 потоков является буферизация.
- С cerr, выход промывает
- немедленно (потому что cerr не использует буфер).
- с засорением, выход промывает
- после завершения текущей функции.
- явный вызов функции flush.
- С cout, выход flushs
- после вызова любых выходных потоков (cout, cerr, забивать.)
- после завершения текущей функции.
- явный вызов функции flush.
пожалуйста, проверьте следующий код и запустите DEBUG через 3 строки: f(std::clog), f(std::cerr), f(std::out), затем откройте 3 выходных файла, чтобы увидеть, что произошло. Вы можете поменять эти 3 строки, чтобы увидеть, что произойдет.
#include <iostream> #include <fstream> #include <string> void f(std::ostream &os) { std::cin.clear(); // clear EOF flags std::cin.seekg(0, std::cin.beg); // seek to begin std::string line; while(std::getline(std::cin, line)) //input from the file in.txt os << line << "\n"; //output to the file out.txt } void test() { std::ifstream in("in.txt"); std::ofstream out("out.txt"), err("err.txt"), log("log.txt"); std::streambuf *cinbuf = std::cin.rdbuf(), *coutbuf = std::cout.rdbuf(), *cerrbuf = std::cerr.rdbuf(), *clogbuf = std::clog.rdbuf(); std::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt! std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt! std::cerr.rdbuf(err.rdbuf()); std::clog.rdbuf(log.rdbuf()); f(std::clog); f(std::cerr); f(std::cout); std::cin.rdbuf(cinbuf); std::cout.rdbuf(coutbuf); std::cerr.rdbuf(cerrbuf); std::clog.rdbuf(clogbuf); } int main() { test(); std::cout << "123"; }
из проекта стандартного документа C++17:
30.4.3 узкие объекты потока [узкий.поток.объекты]
istream cin;
1 объект
cin
контроль ввода из буфера потока, связанного с объектомstdin
, объявленное в<cstdio>
(30.11.1).2 После объекта
cin
инициализацииcin.tie()
возвращает&cout
. Его состояние в противном случае такое же, как требуется дляbasic_ios<char>::init
(30.5.5.2).
ostream cout;
3 объекта
cout
управляет выводом в буфер потока, связанный с объектомstdout
, объявленное в<cstdio>
(30.11.1).
ostream cerr;
4 объекта
cerr
управляет выводом в буфер потока, связанный с объектомstderr
, объявленное в<cstdio>
(30.11.1).5 после объекта
cerr
инициализацииcerr.flags() & unitbuf
не равно нулю иcerr.tie()
возвращает&cout
. Его состояние в противном случае то же самое, что требуется дляbasic_ios<char>::init
(30.5.5.2).
ostream clog;
6 объект
clog
управляет выводом в буфер потока, связанный с объектомstderr
, объявленное в<cstdio>
(30.11.1).Обсуждение...
cout
пишетstdout
;cerr
иclog
доstderr
Стандартный Выход (
stdout
) предназначен для получения безошибочного, недиагностического вывода из программы, например результат успешной обработки, который может быть отображен конечному пользователю или передан на какой-либо следующий этап обработки.Стандартная Ошибка (
stderr
) предназначен для вывода диагностических данных, таких как предупреждения и сообщения об ошибках, которые указывают на то, что программа не произвела или не могла произвести вывод, который может ожидать пользователь. Этот ввод может быть показан конечному пользователю, даже если выходные данные передаются на дальнейшую стадию обработки.
cin
иcerr
привязаны кcout
они оба заподлицо
cout
перед обработкой самих операций ввода-вывода. Это гарантирует, что приглашения будут отправлены наcout
видны перед программными блоками для чтения входных данных изcin
, и что ранее выводcout
сбрасывается перед записью ошибки черезcerr
, который хранит сообщения в хронологическом порядке их генерации, когда оба направлены на один и тот же терминал/файл/и т. д..это контрастирует с
clog
- если вы там пишите он не будет буферизован и не привязан ни к чему, поэтому он будет буферизовать приличное количество журналов перед сбросом. Это дает самую высокую пропускную способность сообщений, но означает, что сообщения не могут быть быстро видны потенциальному потребителю, читающему терминал или следящему за журналом.
и cout и засорить буферизуются, но cerr не буферизуется, и все они являются предопределенными объектами, которые являются экземплярами класса ostream. Основное использование этих трех cout используется для стандартного ввода, тогда как засорить и cerr используется для отображения ошибок. Главное, почему cerr не буферизуется это может быть потому, что у вас есть несколько выходов в буфер и исключение ошибок упоминается в коде, то вам нужно немедленно отобразить эту ошибку, которая может быть выполнена с помощью cerr эффективно.
пожалуйста, поправьте меня, если я ошибаюсь.