В чем разница между 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) с помощью оператора вставки (<<).

не буферизованный стандартный поток ошибок (cerr): cerr стандартный поток ошибок который использован для того чтобы вывести наружу ошибки. Это также экземпляр ostream класса. As cerr is un-buffered поэтому он используется, когда нам нужно немедленно отобразить сообщение об ошибке. Он не имеет буфера для хранения сообщения об ошибке и отображения позже.

Буферизованный стандартный поток ошибок (clog): это также экземпляр ostream класс, и используется для отображения ошибок, но в отличие от cerr ошибка сначала вставляется в буфер и хранится в буфере пока она не заполнится полностью.

читайте далее : basic-вход-выход-c


разница этих 3-х потоков буферизации.

  1. С cerr, выходные промывки
    • немедленно (потому что cerr не использует буфер).
  2. С засор, выход flushs
    • после завершения текущей функции.
    • явным образом вызовите функцию flush.
  3. С 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 to stderr

Стандартный Выход (stdout) предназначено получить non-ошибку, non-диагностический выход от программы, как результат успешной обработки, который может быть отображен конечному пользователю или передан на какой-либо дальнейший этап обработки.

Стандартная Ошибка (stderr) предназначен для диагностических выходных данных, таких как предупреждения и сообщения об ошибках, которые указывают, что программа не произвела или не может произвести вывод, который пользователь может ожидать. Этот вход может отображаться конечному пользователю, даже если выходные данные передаются на дальнейший этап обработки.

cin и cerr привязаны к cout

они оба заподлицо cout перед обработкой самих операций ввода-вывода. Это гарантирует приглашения, отправленные в cout видны перед блоками программы для чтения ввода из cin, и этот более ранний вывод в cout сбрасывается перед записью ошибки через cerr, который сохраняет сообщения в хронологическом порядке их генерации, когда оба направлены на один и тот же терминал/файл/etc..

это контрастирует с clog - если вы там пишите он не будет буферизован и не привязан ни к чему, поэтому он будет буферизировать приличные объемы ведения журнала перед промывкой. Это дает самую высокую пропускную способность сообщений, но означает, что сообщения не могут быть быстро видны потенциальному потребителю, читающему терминал или отслеживающему журнал.


и cout и засорить буферизуются, но cerr не буферизован, и все они являются предопределенными объектами, которые являются экземплярами класса ostream. Основное использование этих трех cout используется для стандартного ввода, тогда как засорить и cerr используется для отображения ошибок. Главное, почему cerr не буферизован может быть, потому что предположим, что у вас есть несколько выходов в буфере и исключение ошибки упоминается в коде, тогда вам нужно немедленно отобразить эту ошибку, которую можно сделать с помощью cerr эффективно.

пожалуйста, поправьте меня, если я ошибаюсь.


cout обычно используется для отображения некоторых операторов на экране пользователя. бывший- : cout

выход:

Арлин Batada