What is good practice for generating verbose output?

前端 未结 5 893
庸人自扰
庸人自扰 2021-02-19 03:49

what is good practice for generating verbose output? currently, i have a function

bool verbose;
int setVerbose(bool v)
{
    errormsg = \"\";
    verbose = v;
           


        
相关标签:
5条回答
  • 2021-02-19 04:00
    int threshold = 3;
    class mystreambuf: public std::streambuf
    {
    };
    mystreambuf nostreambuf;
    std::ostream nocout(&nostreambuf);
    #define log(x) ((x >= threshold)? std::cout : nocout)
    
    int main()
    {
        log(1) << "No hello?" << std::endl;     // Not printed on console, too low log level.
        log(5) << "Hello world!" << std::endl;  // Will print.
        return 0;
    }
    
    0 讨论(0)
  • 2021-02-19 04:01

    You can wrap your functionality in a class that supports the << operator which allows you to do something like

    class Trace {
       public:
          enum { Enable, Disable } state;
       // ...
       operator<<(...)
    };
    

    Then you can do something like

    trace << Trace::Enable;
    trace << "deleting interp"
    
    0 讨论(0)
  • 1. If you are using g++ you could use the -D flag, this allows the compilator to define a macro of your choice.

    Defining the

    For instance :

    #ifdef DEBUG_FLAG
     printf("My error message");
    #endif
    

    2. I agree this isn't elegant either, so to make it a bit nicer :

    void verbose(const char * fmt, ... )
    {
    va_list args;  /* Used as a pointer to the next variable argument. */
    va_start( args, fmt );  /* Initialize the pointer to arguments. */
    
    #ifdef DEBUG_FLAG
    printf(fmt, &args);  
    #endif
    /*This isn't tested, the point is to be able to pass args to 
    printf*/
    }
    

    That you could use like printf :

    verbose("Error number %d\n",errorno);
    

    3. A third solution easier, and more C++ and Unix like is to pass an argument to your program that is going to be used - as the macro earlier - to initialize a particular variable (that could be a global const).

    Example : $ ./myprogram -v

    if(optarg('v')) static const verbose = 1;
    
    0 讨论(0)
  • 2021-02-19 04:13

    The simplest way is to create small class as follows(here is Unicode version, but you can easily change it to single-byte version):

    #include <sstream>
    #include <boost/format.hpp>
    #include <iostream>
    using namespace std;
    
    enum log_level_t {
        LOG_NOTHING,
        LOG_CRITICAL,
        LOG_ERROR,
        LOG_WARNING,
        LOG_INFO,
        LOG_DEBUG
    };
    
    namespace log_impl {
    class formatted_log_t {
    public:
        formatted_log_t( log_level_t level, const wchar_t* msg ) : fmt(msg), level(level) {}
        ~formatted_log_t() {
            // GLOBAL_LEVEL is a global variable and could be changed at runtime
            // Any customization could be here
            if ( level <= GLOBAL_LEVEL ) wcout << level << L" " << fmt << endl;
        }        
        template <typename T> 
        formatted_log_t& operator %(T value) {
            fmt % value;
            return *this;
        }    
    protected:
        log_level_t     level;
        boost::wformat      fmt;
    };
    }//namespace log_impl
    // Helper function. Class formatted_log_t will not be used directly.
    template <log_level_t level>
    log_impl::formatted_log_t log(const wchar_t* msg) {
        return log_impl::formatted_log_t( level, msg );
    }
    

    Helper function log was made template to get nice call syntax. Then it could be used in the following way:

    int main ()
    {
        // Log level is clearly separated from the log message
        log<LOG_DEBUG>(L"TEST %3% %2% %1%") % 5 % 10 % L"privet";
        return 0;
    }
    

    You could change verbosity level at runtime by changing global GLOBAL_LEVEL variable.

    0 讨论(0)
  • 2021-02-19 04:14

    You could use log4cpp

    0 讨论(0)
提交回复
热议问题