Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 694
node ninja Avatar asked May 03 '11 22:05

node ninja


People also ask

How do I use printf instead of cout?

The main difference is that printf() is used to send formated string to the standard output, while cout doesn't let you do the same, if you are doing some program serious, you should be using printf(). As pointed out above, printf is a function, cout an object.

Is printf overloaded?

printf() in C is a variadic function which can be thought of as a form of overloading. Unlike overloaded functions in languages like C++, Java, C# etc., a variadic function is not type-safe which is why they are somewhat frowned upon.

Is cout faster than printf?

To answer your question, printf is faster.

Can I use printf in C++?

Answer: Yes. Printf can be used in C++. To use this function in a C++ program, we need to include the header <cstdio> in the program.


3 Answers

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

....

like image 155
shoosh Avatar answered Oct 20 '22 14:10

shoosh


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
like image 32
Piotr Avatar answered Oct 20 '22 13:10

Piotr


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.

like image 37
deong Avatar answered Oct 20 '22 14:10

deong