node ninja
node ninja

Reputation: 33026

How to overload printf or cout

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 global 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?

Upvotes: 7

Views: 8980

Answers (3)

Piotr
Piotr

Reputation: 833

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:

Upvotes: 3

shoosh
shoosh

Reputation: 79003

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

....

Upvotes: 6

deong
deong

Reputation: 3870

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.

Upvotes: 2

Related Questions