如何重载printf或cout

时间:2011-05-03 22:50:55

标签: c++ debugging function

我在程序中使用cout语句进行调试。我想创建一个像它一样工作的函数,或者像printf一样工作,但是对全局变量很敏感。如果此全局变量为true,则它将打印到屏幕。如果它是假的,那么它将不会打印任何东西。是否已经有这样的功能?如果没有,那怎么可以呢?

3 个答案:

答案 0 :(得分:5)

这样的事情:

int myPrintf(const char* format, ...) 
{
  if (globalCheck == 0)
    return 0
  va_list vl;
  va_start(vl, format);
  auto ret = vprintf(format, vl);
  va_end(vl);
  return ret;
}

va_startva_end获取...中的参数并将其封装在va_list中。使用此va_list,您可以vprintf printf,它是class ConditionalPrinter { public: ConditionalPrinter() : m_enable(true) {} void setOut(bool enable) { m_enable = enable; } int myPrintf(const char* format, ...); private: bool m_enable; } 的变体,专为此需求而设计。

旁注 - 通常使用全局变量是不好的做法。更好的办法是将它封装在这样的类中 -

ConditionalPrinter p;
p.myPrintf("hello %d", 1);   // printed
p.setOut(false);
p.myPrintf("hello2 %d", 1);  // not printed

然后检查m_enable而不是全局变量。 使用方法如下:

{{1}}

...

答案 1 :(得分:3)

不要自己写。做得正确很多比你想象的更难。当你需要线程和效率时更难。使用现有的日志记录库之一,如:

答案 2 :(得分:2)

正如其他人所说,有几个很好的日志框架可用。但是,如果你想自己动手,首先要注意的是cout不是一个函数,它是一个流。该函数是operator<<。您可以做的是以下内容:

/* trace.h */
extern ostream debug;

void trace_init();
void trace_done();

/* trace.cpp */
#include "trace.h"
ostream debug(cout.rdbuf());
static ofstream null;

void trace_init()
{
    null.open("/dev/null");
    if(output_is_disabled) {  // put whatever your condition is here
        debug.rdbuf(null.rdbuf());
    }
}

void trace_done()
{
    null.close();
}

如果你在没有/dev/null的平台上,你可能需要调整一下。这样做是让你写的

debug << "here's some output << endl;

如果您启用了输出,它将写入cout。如果没有,它将写入/dev/null,您将看不到任何内容。

就此而言,你可以将cout的rdbuf设置到你不会看到输出的地方,但我会发现这是一个非常糟糕的主意。创建新流可以更灵活地控制输出。