1

I have output in a C++ program that I only want to see if a "verbose" option is specified at runtime. I've found lots of methods to use preprocessor #define statements to control debugging output when compiling, but I can't find any ways to do this at runtime short of wrapping every cout in if(verbose).

In pseudocode, I'd like to transform:

if(verbose)
  cout << "Some text: " << variable << endl;
...
if(verbose)
  cout << "Other text: " << var << endl;

Into:

if(verbose)
  //block cout

cout << "Some text: " << variable << endl;
cout << "Other text: " << var << endl;

Is there some way to optionally redefine cout at runtime so those lines silently print nothing? Better yet would be a more flexible approach that allows some output while blocking others.

jake
  • 361
  • 1
  • 14
  • `cout` is character out, distinguished from `wcout` (wide-character out). It is not "console". Do not conflate stdout with a tty. – William Pursell Dec 11 '14 at 15:15
  • http://stackoverflow.com/questions/7721026/programatically-ignore-cout :-) – splrs Dec 11 '14 at 15:16
  • @WilliamPursell I don't fully understand the distinction you're making. This is a program that runs in a terminal and any cout statements appear in the terminal (which I understand to be stdout). Should the question begin "I have tty output..."? – jake Dec 11 '14 at 15:19
  • Your question talks about "console output". But there is nothing related to a 'console' anywhere in your code unless you mistakenly assume that stdout is a console. I am pointing out that it is a mistake to think that stdout is a console. – William Pursell Dec 11 '14 at 15:20
  • @jake It depends on the system. At least under Unix and Windows, regardless of where the program runs, there is no assurance that `std::cout` goes to the console; both systems support pipes and redirection. – James Kanze Dec 11 '14 at 15:35
  • @jake Which, of course, is the logical answer to your question. Under Windows, just invoke the program with `prog >nul`; under Unix, with `prog >/dev/null`. – James Kanze Dec 11 '14 at 15:36
  • @JamesKanze: considering the OP's requirements, I think you mean `2>nul` and (if this notation works in Unix-land) `2>/dev/null`. That takes care of `std::clog`. Among others. – Cheers and hth. - Alf Dec 11 '14 at 15:37
  • @Alf I don't know what the OP's requirements are (although I suspect that an explicitly opened file would be most appropriate), but his question concerned `std::cout` (and the notation originated in Unix-land; I was using it when Windows was still MS-DOS version 1). – James Kanze Dec 11 '14 at 15:55
  • @JamesKanze: I was referring to "Better yet would be a more flexible approach that allows some output while blocking others.". Which could be done by having all the verbose output going to `std::clog`. In which case redirection of that to thebbbits (the big bit bucket in the sky) would remove the verbosity and leave the kernel output. But evidently I misunderstood you. Or the OP. :-) – Cheers and hth. - Alf Dec 11 '14 at 15:59
  • @JamesKanze and Alf - I'm trying to limit cout statements in class methods invoked from main. I don't want to redirect the entire program into a file or /dev/null. – jake Dec 11 '14 at 16:36
  • @JamesKanze and William: I said console because I knew I wasn't redirecting or piping stdout. Question edited to remove "console." Does this make the question correct? – jake Dec 11 '14 at 16:41

2 Answers2

3

You can simply bind a stream object reference to different streams depending on verbose:

ostream& vout = (verbose? cout : nullstream);

Then use vout for all the output that should only appear when verbose.

Of course you need to define nullstream first; that involves defining a streambuf derived class.

Community
  • 1
  • 1
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • This looks like exactly what I need, but I have to digest the information about defining nullstream. – jake Dec 11 '14 at 16:36
  • @jake: actually [James Kanze has answered that](http://stackoverflow.com/questions/8243743/is-there-a-null-stdostream-implementation-in-c-or-libraries) (I didn't notice when I wrote the above), and there's also a Ready To Use™ implementation in Boost. – Cheers and hth. - Alf Dec 11 '14 at 17:12
0

I'm not sure whether you're in the process of writing a program, or whether you already have a program you want to disable output for. Generally, when you're writing software with debugging output, you'll want to create some sort of logging class to help you control when output occurs and where it goes (e.g., to a file, to stdout, to stderr, etc.). An example of a simple one would be:

#include <iostream>

class Logger {

public:
    Logger(bool enabled) : enabled(enabled) { }
    void setEnabled(bool enabled) { this->enabled = enabled; }

    template<typename T> Logger& operator<<(T const& t)
    {
        if (enabled)
            std::cout << t;
        return *this;
    }

    // If you'd like manipulator support (e.g., for std::endl)
    Logger& operator<<(std::ostream& (*manipulator)(std::ostream&))
    {
        if (enabled)
            std::cout << manipulator;
        return *this;
    }

private:
    bool enabled;
};

int main()
{
    Logger log(true);
    log << "Hello, " << "World!" << 123; // Prints Hello, World!123

    log.setEnabled(false);
    log << "Hello, " << "World!" << 123; // Prints nothing
}

Alternatively, you could redirect cout, as others have mentioned, or even just simply redirect your program's output to /dev/null on the command line:

./myProgram > /dev/null
Julian
  • 1,688
  • 1
  • 12
  • 19
  • Thanks for fixing that @Cheersandhth.-Alf. For sure; looks good! Just going to add a comment indicating what that part is for, in case OP or any new readers aren't familiar with it. – Julian Dec 11 '14 at 16:05