我一直在想,堵住有什么意义?据我所知, clog 与 cerr 相同,但有缓冲,因此效率更高。通常 stderr 与 stdout 相同,因此 clog 与 cout 相同。这对我来说似乎很蹩脚,所以我想我一定是误解了它。如果我有日志消息发送到同一个地方,我有错误消息发送到(可能是 /var/log/messages 中的某些内容),那么我可能不会写太多(因此使用非-缓冲cerr)。根据我的经验,我希望我的日志消息是最新的(而不是缓冲的),这样我就可以帮助找到崩溃(所以我不想使用缓冲的堵塞)。显然我应该始终使用 cerr。

我希望能够在我的程序中重定向阻塞。重定向 cerr 会很有用,这样当我调用库例程时,我可以控制 cerr 和 clog 的去向。有些编译器可以支持这个吗?我刚刚检查了 DJGPP,stdout 被定义为 FILE 结构的地址,因此执行“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 shell环境中(我真的在想BASH),则可以将任何文件描述符重定向到任何其他文件描述符,因此要重定向,您可以:

$ myprogram 2>&5 

将 stderr 重定向到 fd=5 表示的文件。

编辑:再想一想,我更喜欢@Konrad Rudolph 关于重定向的回答。rdbuf() 是一种更连贯且可移植的方法。

至于日志记录,嗯...我从 Boost 库开始处理 std 库中没有的所有 C++ 内容。看哪: 增强日志记录 v2

编辑: :增强日志记录是 不是 Boost 库的一部分;它已被审查,但未被接受。

编辑: :2 年后,即 2010 年 5 月,Boost 确实接受了一个日志库,现在称为 升压日志.

当然,还有其他选择:

  • Log4Cpp (用于 C++ 的 log4j 风格 API)
  • Log4Cxx (Apache 赞助的 log4j 风格的 API)
  • 潘泰奥斯 (已失效?上次我尝试时无法让它在最新的编译器上构建)
  • 谷歌的GLog (帽子提示@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