开发者

How to overload printf or cout

开发者 https://www.devze.com 2023-03-02 08:17 出处:网络
I use cout statements in my program for debugging purposes. I would like to make a function that works like it, or works like printf, but is sensitive to a globa开发者_开发百科l variable. If this glob

I use cout statements in my program for debugging purposes. I would like to make a function that works like it, or works like printf, but is sensitive to a globa开发者_开发百科l variable. If this global variable is true, then it will print to screen. If it is false, then it won't print anything. Is there already a function like this? If not, then how can it be made?


Something like this:

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_start and va_end take the arguments in the ... and encapsulate them in a va_list. with this va_list you can then the vprintf which is a variant of printf designed exactly for this need.

Side note - usually it is bad practice to use global variables. A better thing to do is to encapsulate it in a class like this -

class ConditionalPrinter {
public:
  ConditionalPrinter() : m_enable(true) {}
  void setOut(bool enable) { m_enable = enable; }
  int myPrintf(const char* format, ...);
private:
  bool m_enable;
}

and then to check m_enable instead of the global variable. Usage of this looks like this:

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

....


Don't write it yourself. Doing it right is much harder then you think. Even harder when you need threads and efficiency. Use one of existing logging libraries like:

  • glog: http://code.google.com/p/google-glog/ (I prefer this - it is lightweight and do what it needs to do)
  • Log4cpp http://log4cpp.sourceforge.net/ (powerful and configuration compatible with popular java logging)
  • ... add your favorite to this wiki


As someone else said, there are several good logging frameworks available. However, if you want to roll your own, the first thing to note is that cout isn't a function, it's a stream. The function is operator<<. What you can do is something like the following:

/* 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();
}

You might have to adjust a bit if you're on a platform without /dev/null. What this does is let you write

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

and if you have the output enabled, it will write to cout. If not, it will write to /dev/null where you won't see anything.

For that matter, you could just set cout's rdbuf to somewhere where you won't see that output, but I would find that to be a really bad idea. Creating new streams gives you a lot more flexibility in controlling your output.

0

精彩评论

暂无评论...
验证码 换一张
取 消