Я пытался исследовать разницу между cout
, cerr
а также clog
в интернете, но не смог найти идеальный ответ. Я до сих пор не ясно, когда использовать какой. Может ли кто-нибудь объяснить мне через простые программы и проиллюстрировать идеальную ситуацию, когда использовать какую?
я навестил этот сайт которая показывает небольшую программу на cerr
а также clog
, но вывод, полученный там, также может быть получен с использованием cout
, Итак, я запутался в точном использовании каждого из них.
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
ошибка сначала вставляется в буфер и сохраняется в буфере, пока не будет заполнен полностью.
дальнейшее чтение : базовый ввод-вывод-с
Разница этих 3 потоков в буферизации.
Пожалуйста, проверьте следующий код и запустите 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
— если вы напишите там, он не будет буферизован и ни к чему не привязан, поэтому он будет буферизовать приличное количество журналов перед сбросом. Это дает наивысшую пропускную способность сообщений, но означает, что сообщения могут быть не быстро видны потенциальному потребителю, читающему терминал или следящему за журналом.
И то и другое соиЬ а также загромождать буферизованы но сегг небуферизован, и все это предопределенные объекты, которые являются экземплярами класса ostream.
Основное использование этих трех соиЬ используется для стандартного ввода, тогда как загромождать а также сегг используется для отображения ошибок.
Суть почему сегг небуферизован, может быть потому, что у вас есть несколько выходов в буфере, и в коде упоминается исключение ошибки, тогда вам нужно немедленно отобразить эту ошибку, что может быть сделано сегг эффективно.
Пожалуйста, поправьте меня, если я ошибаюсь.
cout обычно используется для отображения некоторых операторов на экране пользователя.
экс-
:
соиЬ<<«Арлена Батада»;
выход:
Арлин Батада