加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 将调试输出重定向到空流而不是std :: cerr

发布时间:2020-12-16 09:47:55 所属栏目:百科 来源:网络整理
导读:我正在使用的软件库将大量调试输出写入std :: cerr,但如果我告诉它安静,则将该输出重定向到空流.这是一个简化的main.cpp,它显示了代码如何尝试实现此目的: #include iostream#include fstream#include cassert// The stream that debug output is sent to.
我正在使用的软件库将大量调试输出写入std :: cerr,但如果我告诉它安静,则将该输出重定向到空流.这是一个简化的main.cpp,它显示了代码如何尝试实现此目的:

#include <iostream>
#include <fstream>
#include <cassert>

// The stream that debug output is sent to. By default
// this points to std::cerr.
std::ostream* debugStream(&std::cerr);

// Throughout the library's codebase this function is called
// to get the stream that debug output should be sent to.
std::ostream& DebugStream()
{
    return *debugStream;
}

// Null stream. This file stream will never be opened and acts
// as a null stream for DebugStream().
std::ofstream nullStream;

// Redirects debug output to the null stream
void BeQuiet()
{
    debugStream = &nullStream;
}

int main(int argc,char** argv)
{
  DebugStream() << "foo" << std::endl;
  BeQuiet();
  DebugStream() << "bar" << std::endl;
  assert(debugStream->good());

  return 0;
}

运行此程序时,您会注意到字符串“bar”已正确发送到空流.但是,我注意到断言失败了.这是我应该关注的吗?或者这只是图书馆开发人员选择的方法的一个稍微丑陋的细节?

如果您愿意,欢迎提出更好的替代方案.一些限制:

>库是跨平台的,所以我认为使用open / dev / null不是一个有效的解决方案,因为它在Windows上不起作用
>库使用标准C,因此任何替代解决方案都不应使用特定于编译器的东西

解决方法

没有必要担心流不好()!由于输出运算符在故障模式中没有真正做任何事情,所以记录的不同实体没有被格式化,即,与替代方法相比,代码确实运行得更快.

请注意,您确实不需要第二个流来禁用输出:

>假设所有输出运算符都表现良好,您只需设置std :: ios_base :: failbit:

debugStream().setstate(std::ios_base::failbit);

>如果有错误的输出写入流即使它不好()你可以将其流缓冲区设置为null:

debugStream()rdbuf(nullptr).

如果你真的希望你的流保持在good()状态,你将安装一个只消耗字符的流缓冲区.但是请注意,您希望为此流缓冲区提供缓冲区,因为为每个char调用overflow()是相当冒犯的:

struct nullbuf
    : std::streambuf {
    char buf[256];
    int overflow(int c) {
        this->setp(this->buf,this->buf + 256);
        return std::char_traits<char>::not_eof(c);
    }
};
...
nullbuf sbuf;
debugStream().rdbuf(&sbuf);
...
debugStream().rdbuf(0);

有必要重置流的流缓冲区,因为std :: ostream的析构函数将刷新stresm缓冲区(即,它调用pubsync()).在已销毁的流缓冲区上执行此操作将不起作用.

就个人而言,我会设置std :: ios_base :: failbit.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读