如何重载打印或计数

How to overload printf or cout

本文关键字:打印 重载 何重载      更新时间:2023-10-16

我在程序中使用cout语句是为了调试目的。我想做一个像它一样工作的函数,或者像printf一样工作,但对全局变量很敏感。如果这个全局变量为真,那么它将打印到屏幕上。如果它为假,那么它不会打印任何东西。已经有这样的函数了吗?如果不是,那怎么做呢?

像这样:

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

,然后检查m_enable而不是全局变量。this的用法如下:

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

不要自己写。做对比你想象的要困难得多。当您需要线程和效率时就更难了。使用现有的日志库之一,如:

  • glog: https://github.com/google/glog(我更喜欢这个-它是轻量级的,做它需要做的)
  • Log4cpp http://log4cpp.sourceforge.net/(功能强大,配置与流行的java日志兼容)
  • …把你喜欢的添加到这个wiki

正如其他人所说,有几个很好的日志框架可用。然而,如果你想滚动你自己的,首先要注意的是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的rbuf设置到您不会看到输出的地方,但我认为这是一个非常糟糕的主意。创建新的流可以让你更灵活地控制输出