Вопрос

Мне было интересно, в чем смысл засорения?Насколько я могу судить, clog - это то же самое, что cerr, но с буферизацией, поэтому он более эффективен.Обычно stderr - это то же самое, что и stdout, поэтому clog - это то же самое, что cout.Мне это кажется довольно неубедительным, поэтому я полагаю, что, должно быть, неправильно понял.Если у меня есть сообщения журнала, отправляющиеся в то же место, куда у меня отправляются сообщения об ошибках (возможно, что-то в /var/log/messages), то я, вероятно, не записываю слишком много (так что при использовании небуферизованного cerr теряется не так много).По моему опыту, я хочу, чтобы мои сообщения журнала были актуальными (не буферизованными), чтобы я мог помочь найти сбой (поэтому я не хочу использовать буферизованный clog).Очевидно, я всегда должен использовать cerr.

Я хотел бы иметь возможность перенаправлять clog внутри моей программы.Было бы полезно перенаправить cerr, чтобы при вызове библиотечной процедуры я мог контролировать, куда переходят cerr и clog.Могут ли некоторые компиляторы поддерживать это?Я только что проверил DJGPP, и stdout определяется как адрес ФАЙЛОВОЙ структуры, поэтому незаконно делать что-то вроде "stdout = freopen(...)".

  • Можно ли перенаправить clog, cerr, cout, stdin, stdout и / или stderr?
  • Является ли единственная разница между clog и cerr буферизацией?
  • Как мне реализовать (или найти) более надежное средство ведения журнала (ссылки, пожалуйста)?
Это было полезно?

Решение

Можно ли перенаправить clog, cerr, cout, stdin, stdout и / или stderr?

ДА.Вы хотите, чтобы rdbuf функция.

ofstream ofs("logfile");
cout.rdbuf(ofs.rdbuf());
cout << "Goes to file." << endl;

Является ли единственная разница между clog и cerr буферизацией?

Насколько я знаю, да.

Другие советы

Если вы работаете в среде оболочки posix (я действительно думаю о bash), вы можете перенаправить любой файловый дескриптор на любой другой файловый дескриптор, поэтому для перенаправления вы можете просто:

$ myprogram 2>&5 

перенаправить stderr в файл, представленный fd=5.

Редактировать:если подумать, мне больше нравится ответ @Konrad Rudolph о перенаправлении.rdbuf() - более последовательный и переносимый способ сделать это.

Что касается ведения журнала, хорошо...Я начну с библиотеки Boost для всего, что связано с C ++, которой нет в библиотеке std.Узрите: Ускоренное ведение журнала v2

Редактировать:Ведение журнала Boost - это нет часть библиотек Boost;оно было рассмотрено, но не принято.

Редактировать:2 года спустя, еще в мае 2010 года, Boost принял библиотеку ведения журнала, которая теперь называется Boost.Войти.

Конечно, есть альтернативы:

  • Log4Cpp (API в стиле log4j для C ++)
  • Log4Cxx (API в стиле log4j, спонсируемый Apache)
  • Пантеос (несуществующий?в прошлый раз, когда я пытался, мне не удалось создать его на основе последнего компилятора)
  • Глог от Google (кончик шляпы @SuperElectric)

Существует также регистратор событий Windows.

И еще пара статей, которые могут оказаться полезными:

Базовый Регистратор

#define myerr(e) {CriticalSectionLocker crit; std::cerr << e << std::endl;}

Используется как myerr("ERR: " << message); или myerr("WARN: " << message << code << etc);

Это очень эффективно.

Тогда делай:

./programname.exe 2> ./stderr.log
perl parsestderr.pl stderr.log

или просто проанализируйте stderr.log вручную

Я признаю, что это не для чрезвычайно код, критичный к производительности.Но кто все равно это пишет?

Поскольку здесь есть несколько ответов о перенаправлении, я добавлю этот прекрасный драгоценный камень Недавно я наткнулся на статью о перенаправлении:

#include <fstream>
#include <iostream>

class redirecter
{
public:
    redirecter(std::ostream & dst, std::ostream & src)
        : src(src), sbuf(src.rdbuf(dst.rdbuf())) {}
    ~redirecter() { src.rdbuf(sbuf); }
private:
    std::ostream & src;
    std::streambuf * const sbuf;
};

void hello_world()
{
    std::cout << "Hello, world!\n";
}

int main()
{
    std::ofstream log("hello-world.log");
    redirecter redirect(log, std::cout);
    hello_world();
    return 0;
}

По сути, это класс перенаправления, который позволяет вам перенаправлять любые два потока и восстанавливать его, когда вы закончите.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top