Я пытался исследовать разницу между cout
, cerr
и clog
в Интернете , но не мог найти идеальный ответ. Я до сих пор не понимаю, когда использовать. Может ли кто-нибудь объяснить мне с помощью простых программ и проиллюстрировать идеальную ситуацию, когда использовать какую?
Я посетил этот сайт, который показывает небольшую программу на cerr
и clog
, но результат, полученный там, также можно получить с помощью cout
. Итак, я запутался в точном использовании каждого из них.
stdout
,stdin
(дляcin
),stderr
который он использует по умолчанию. Я считаю, чтоclog
это простоcerr
с изменением буферизации.Ответы:
stdout
иstderr
являются разными потоками, хотя по умолчанию они оба относятся к выходу консоли. Перенаправление (соединение) одного из них (напримерprogram.exe >out.txt
) не повлияет на другой.Как правило, его
stdout
следует использовать для фактического вывода программы, в то время как вся информация и сообщения об ошибках должны быть распечатаныstderr
, чтобы, если пользователь перенаправляет вывод в файл, информационные сообщения по-прежнему выводились на экран, а не в выходной файл.источник
Обычно вы используете
std::cout
для нормального вывода,std::cerr
для ошибок иstd::clog
для «ведения журнала» (что может означать все, что вы хотите).Основное отличие состоит в том, что
std::cerr
он не буферизуется, как два других.По отношению к старому C
stdout
иstderr
,std::cout
соответствуетstdout
, в то время какstd::cerr
иstd::clog
обе соответствуетstderr
( за исключением того, чтоstd::clog
в буфер).источник
clog
также выводит наcerr
. Итак, исходя из этого, какой из них вы выберете? Еслиclog
это обычно для «ведения журнала», почему я должен отправлять его в поток ошибок? Журналы больше похожи на «обычные журналы» (иначеcout
), чем на ошибки.cerr
иclog
используют стандартный вывод «ошибок», ноclog
буферизуются, что может быть поэтому больше похожеcout
. Какой выбрать для вывода ошибок? Зависит, я полагаю, по большему количеству причин, чем я могу перечислить, и это нужно решать от случая к случаю.Стандартный выходной поток (cout):
cout
это экземплярostream
класса.cout
используется для вывода на стандартное устройство вывода, которым обычно является экран дисплея. Данные, необходимые для отображения на экране, вставляются в стандартный поток вывода (cout
) с помощью оператора вставки (<<
).Небуферизованный стандартный поток ошибок (cerr):
cerr
стандартный поток ошибок, который используется для вывода ошибок. Это тоже экземплярostream
класса. Посколькуcerr
он не буферизован, он используется, когда нам нужно немедленно отобразить сообщение об ошибке. У него нет буфера для хранения сообщения об ошибке и последующего отображения.Буферизованный стандартный поток ошибок (clog): это также экземпляр
ostream
класса и используется для отображения ошибок, но в отличиеcerr
от ошибки сначала вставляется в буфер и сохраняется в буфере до тех пор, пока он не будет полностью заполнен.дальнейшее чтение: базовый-ввод-вывод-c
источник
until it is not fully filled.
- разве это не говоритuntil it IS fully filled
?Отличие этих трех потоков в буферизации.
Проверьте следующий код и запустите 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:
Обсуждение ...
cout
пишет вstdout
;cerr
иclog
чтобыstderr
Стандартный выход (
stdout
) предназначен для получения не содержащих ошибок, недиагностических выходных данных из программы, таких как выходные данные успешной обработки, которые могут быть отображены конечному пользователю или переданы на какой-либо дальнейший этап обработки.Стандартная ошибка (
stderr
) предназначена для диагностического вывода, такого как предупреждения и сообщения об ошибках, которые указывают на то, что программа не выдала или, возможно, не выдала вывод, который мог бы ожидать пользователь. Этот ввод может отображаться для конечного пользователя, даже если выходные данные передаются на этап дальнейшей обработки.cin
иcerr
привязаны кcout
Оба они сбрасываются
cout
перед обработкой самих операций ввода-вывода. Это гарантирует, что отправляемые приглашенияcout
будут видны до того, как программа будет блокирована для чтения вводаcin
, и что предыдущий выводcout
будет сброшен перед записью ошибкиcerr
, что сохраняет сообщения в хронологическом порядке их генерации, когда оба направлены на один и тот же терминал / файл / так далее..Это контрастирует с тем, что
clog
если вы напишете там, он не будет буферизован и ни к чему не привязан, поэтому он будет буферизовать приличный объем журналов перед сбросом. Это обеспечивает наивысшую пропускную способность сообщений, но означает, что сообщения могут не быть быстро видимыми для потенциального потребителя, читающего терминал или заканчивающего журнал.источник
И cout, и clog буферизуются, но cerr не буферизуется, и все это предопределенные объекты, которые являются экземплярами класса ostream. Базовое использование этих трех: cout используется для стандартного ввода, тогда как clog и cerr используются для отображения ошибок. Основная причина, по которой cerr не буферизуется, может заключаться в том, что предположим, что у вас есть несколько выходных данных в буфере и в коде упоминается исключение ошибки, тогда вам необходимо немедленно отобразить эту ошибку, что может быть эффективно выполнено с помощью cerr .
Пожалуйста, поправьте меня, если я ошибаюсь.
источник