Pergunta

Fiquei me perguntando: qual é o sentido do entupimento?Pelo que posso dizer, clog é o mesmo que cerr, mas com buffer, por isso é mais eficiente.Normalmente stderr é igual a stdout, então clog é igual a cout.Isso parece muito idiota para mim, então acho que devo estar entendendo mal.Se eu tiver mensagens de log enviadas para o mesmo local para onde recebo mensagens de erro (talvez algo em /var/log/messages), provavelmente não estou escrevendo muito (portanto, não há muita perda usando não - cerr tamponado).Na minha experiência, quero minhas mensagens de log atualizadas (não armazenadas em buffer) para poder ajudar a encontrar uma falha (portanto, não quero usar o entupimento em buffer).Aparentemente, eu deveria estar sempre usando cerr.

Gostaria de poder redirecionar o entupimento dentro do meu programa.Seria útil redirecionar cerr para que, quando eu chamar uma rotina de biblioteca, eu possa controlar para onde vão cerr e clog.Alguns compiladores podem suportar isso?Acabei de verificar o DJGPP e o stdout é definido como o endereço de uma estrutura FILE, portanto é ilegal fazer algo como "stdout = freopen (...)".

  • É possível redirecionar clog, cerr, cout, stdin, stdout e/ou stderr?
  • A única diferença entre entupir e cerr é o buffer?
  • Como devo implementar (ou encontrar) um recurso de registro mais robusto (links, por favor)?
Foi útil?

Solução

É possível redirecionar clog, cerr, cout, stdin, stdout e/ou stderr?

Sim.Você quer o rdbuf função.

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

A única diferença entre entupir e cerr é o buffer?

Pelo que eu sei, sim.

Outras dicas

Se você está em um ambiente de shell POSIX (estou realmente pensando em Bash), pode redirecionar qualquer descritor de arquivo para qualquer outro descritor de arquivo; portanto, para redirecionar, você pode apenas:

$ myprogram 2>&5 

para redirecionar stderr para o arquivo representado por fd=5.

Editar:pensando bem, gosto mais da resposta de @Konrad Rudolph sobre redirecionamento.rdbuf() é uma maneira mais coerente e portátil de fazer isso.

Quanto ao registro, bem... começo com a biblioteca Boost para todas as coisas C++ que não estão na biblioteca std.Contemplar: Aumente o registro v2

Editar:O registro de reforço é não parte das Bibliotecas Boost;foi revisado, mas não aceito.

Editar:2 anos depois, em maio de 2010, Boost aceitou uma biblioteca de registro, agora chamada Impulsionar.Log.

Claro, existem alternativas:

  • Log4Cpp (uma API estilo log4j para C++)
  • Log4Cxx (API estilo log4j patrocinada pelo Apache)
  • Panteios (extinto?da última vez que tentei, não consegui construir em um compilador recente)
  • GLog do Google (gorjeta @SuperElectric)

Há também o registrador de eventos do Windows.

E alguns artigos que podem ser úteis:

Registrador Básico

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

Usado como myerr("ERR: " << message); ou myerr("WARN: " << message << code << etc);

É muito eficaz.

Então faça:

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

ou apenas analise stderr.log manualmente

Eu admito que isso não é para extremamente código crítico de desempenho.Mas quem escreve isso de qualquer maneira.

Como há várias respostas aqui sobre redirecionamento, acrescentarei esta bela jóia Me deparei recentemente com o redirecionamento:

#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;
}

É basicamente uma classe de redirecionamento que permite redirecionar quaisquer dois fluxos e restaurá-los quando terminar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top