1

I am trying to control the print outs in my program. I wrote a small script for that which takes a command line argument and decides to print or not to print depending upon the flag -v passed to it. Now I have to write out(bool) in my actual program everywhere. Is it possible to make the decision in the start of the program and just to use out instead of out(bool).

class mystreambuf : public std::streambuf { }; mystreambuf nostreambuf; std::ostream nocout(&nostreambuf); #define out(b) ((b==true)?std::cout : nocout ) int main(int argc, char* argv[]) { std::cout << "Program name is: " << argv[0] << "\n"; int counter; bool verbose; if (argc == 1) { std::cout << "No command line argument passed" << argv[0] << "\n"; } if (argc >= 2) { for (counter = 0; counter < argc; counter++) { std::cout << "Argument passed are: " << argv[counter] << "\n"; if (strcmp(argv[counter], "-v") == 0) { verbose = true; } else { verbose = false; } } } out(verbose) << "\n hello world \n"; system("pause"); } 
2
  • 2
    This sounds like what you really need is a logging framework... Commented Jul 10, 2018 at 8:45
  • As a general rule, avoid using the constant true and false in your code, they are virtually always unnecessary, and only add verbosity, which decreases readability. Don’t write b == true, write just b. Same for your (ironically named) verbose assignment: this can and should be accomplished in a single line (instead of eight): verbose = strcmp(argv[counter], "-v") == 0; — Furthermore, out should be a function, not a macro. Commented Jul 10, 2018 at 9:55

3 Answers 3

1

A simple way would be to build a minimal class containing the boolean flag and a reference to the actual stream. Then the << operator would be either a no-op or a delegation to the actual stream. It could be:

class LogStream { std::ostream& out; bool verbose; public: LogStream(std::ostream& out = std::cout): out(out) {} void set_verbose(bool verbose) { this->verbose = verbose; } template <class T> LogStream& operator << (const T& val) { if (verbose) { out << val; } return *this; } }; 

It can then be used that way:

int main(int argc, char* argv[]) { LogStream out; ... out.set_verbose(verbose); out << "\n hello world \n"; ... } 
Sign up to request clarification or add additional context in comments.

Comments

1

You could make a singleton instance that you setup at the beginning and log through. Something like:

class Printer { public: static std::streambuf getInstance() { if (_instance._printing) { return std::cout; } return _instance._nostreambuf; } static void setPrinting(bool set) { _instance._printing = set; } private: static Printer _instance; mystreambuf _nostreambuf; bool _printing; // delete constructors and assignment operators. } 

Note: Rapid pseudo code, not tested.

Which you would use like:

Printer::setPrinting(verboseBool); Printer::getInstance() << "Print text"; 

But what you would be making is a logger. Of which there are plenty. Here is a nice list.

Comments

0

Simply make out a variable being one of the two options:

std::ostream &out = verbose ? std::cout : nocout; 

and continue printing with out <<

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.