В чем разница между cout, cerr, засорением заголовка iostream в C++? Когда использовать какой?
Я пытался исследовать разницу между cout
, cerr
а также clog
в интернете, но не смог найти идеальный ответ. Я до сих пор не ясно, когда использовать какой. Может ли кто-нибудь объяснить мне через простые программы и проиллюстрировать идеальную ситуацию, когда использовать какую?
Я посетил этот сайт, который показывает небольшую программу на cerr
а также clog
, но вывод, полученный там, также может быть получен с помощью cout
, Итак, я запутался в точном использовании каждого из них.
8 ответов
stdout
а также stderr
это разные потоки, хотя они оба ссылаются на вывод консоли по умолчанию. Перенаправление (обвязка) одного из них (например, program.exe >out.txt
) не повлияет на других.
В общем-то, stdout
должны использоваться для фактического вывода программы, тогда как вся информация и сообщения об ошибках должны быть напечатаны на stderr
, так что если пользователь перенаправляет вывод в файл, информационные сообщения все еще печатаются на экране, а не в выходной файл.
Как правило, вы используете std::cout
для нормального выхода, std::cerr
за ошибки и std::clog
для "регистрации" (что может означать все, что вы хотите, чтобы это значило).
Основное отличие состоит в том, что std::cerr
не буферизуется, как два других.
По отношению к старому С stdout
а также stderr
, std::cout
соответствует stdout
, в то время как std::cerr
а также std::clog
оба соответствуют stderr
(Кроме этого std::clog
буферизован).
Стандартный поток вывода (cout): cout
это пример ostream
учебный класс. cout
используется для вывода на стандартное устройство вывода, которым обычно является экран дисплея. Данные, которые необходимо отобразить на экране, вставляются в стандартный поток вывода (cout
) используя оператор вставки (<<
).
Небуферизованный стандартный поток ошибок (cerr): cerr
стандартный поток ошибок, который используется для вывода ошибок. Это также пример ostream
учебный класс. Как cerr
не буферизован, поэтому он используется, когда нам нужно немедленно отобразить сообщение об ошибке. У него нет буфера для хранения сообщения об ошибке и отображения позже.
Буферизированный стандартный поток ошибок (засорение): это также экземпляр ostream
класс и используется для отображения ошибок, но в отличие cerr
ошибка сначала вставляется в буфер и сохраняется в буфере до ее полного заполнения.
дальнейшее чтение: basic-input-output-c
cerr не требует буфера, поэтому он быстрее других и не использует память, которую использует cout, но поскольку cout буферизован, в некоторых случаях он более полезен. Так:
- Используйте cout для стандартного вывода.
- Используйте cerr для отображения ошибок.
- Используйте засорение для регистрации.
Разница этих трех потоков в буферизации.
- С cerr, выходные сбрасывает
- немедленно (потому что cerr не использует буфер).
- С засорением, выход сбрасывает
- после того, как вы закончите свою текущую функцию.
- явно вызвать функцию flush.
- С cout, вывод сбрасывает
- после вызова любых потоков вывода (cout, cerr, clog).
- после того, как вы закончите свою текущую функцию.
- явно вызвать функцию 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 Объекты с узким потоком [thin.stream.objects]
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, и clog буферизируются, но cerr не буферизируется, и все они являются предопределенными объектами, которые являются экземплярами класса ostream. Основное использование этих трех: cout используется для стандартного ввода, тогда как clog и cerr используется для отображения ошибок. Основная причина, по которой cerr не буферизован, может заключаться в том, что если у вас есть несколько выходов в буфере, а в коде упоминается исключение ошибки, то вам нужно немедленно отобразить эту ошибку, что может быть эффективно сделано cerr.
Пожалуйста, поправьте меня, если я ошибаюсь.
cout обычно используется для отображения некоторых операторов на экране пользователя. ex-: cout<< "Арлин Батада";
выход:
Арлин Батада