C++动态启用/禁用std :: couts的调试消息

Car*_*ndo 17 c++ debugging

有没有办法在程序内部使用std :: cout定义/取消定义调试消息?

我知道有像#define,#ifnf这样的东西,但我在想是否有更简洁的方法让变量说:

# debug ON
Run Code Online (Sandbox Code Playgroud)

这将打印我的所有调试数据(使用std :: cout).因此,我们将使用这样的代码进行调试:

#ifndef DEBUG
// do something useful
#endif
Run Code Online (Sandbox Code Playgroud)

当你编写100个调试代码时,我发现上面的代码很麻烦.

谢谢!

卡罗

Gia*_*nni 35

#ifdef DEBUG
#define DEBUG_MSG(str) do { std::cout << str << std::endl; } while( false )
#else
#define DEBUG_MSG(str) do { } while ( false )
#endif

int main()
{
    DEBUG_MSG("Hello" << ' ' << "World!" << 1 );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • @cYrus强迫你把';' 在每次*的宏调用结束时*.确保:if(c)MACRO(param)\ func(other); 如果(c)func(其他)不会成为; 当宏被扩展为"空"文本时(即没有';') (8认同)
  • 这里`do while`的目的是什么? (5认同)

Mic*_*l J 7

除非您有复杂的日志记录需求,否则一些日志库非常重要.这是我刚碰到的东西.需要一些测试,但可能符合您的要求:

#include <cstdio>
#include <cstdarg>

class CLog
{
public:
    enum { All=0, Debug, Info, Warning, Error, Fatal, None };
    static void Write(int nLevel, const char *szFormat, ...);
    static void SetLevel(int nLevel);

protected:
    static void CheckInit();
    static void Init();

private:
    CLog();
    static bool m_bInitialised;
    static int  m_nLevel;
};

bool CLog::m_bInitialised;
int  CLog::m_nLevel;

void CLog::Write(int nLevel, const char *szFormat, ...)
{
    CheckInit();
    if (nLevel >= m_nLevel)
    {
        va_list args;
        va_start(args, szFormat);
        vprintf(szFormat, args);
        va_end(args);
    }
}
void CLog::SetLevel(int nLevel)
{
    m_nLevel = nLevel;
    m_bInitialised = true;
}
void CLog::CheckInit()
{
    if (!m_bInitialised)
    {
        Init();
    }
}
void CLog::Init()
{
    int nDfltLevel(CLog::All);
    // Retrieve your level from an environment variable, 
    // registry entry or wherecer
    SetLevel(nDfltLevel);
}

int main()
{
    CLog::Write(CLog::Debug, "testing 1 2 3");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


NG.*_*NG. 5

可能不是.我建议使用日志库.我不确定C++的最佳选择是什么,但我过去使用过log4cpp并发现它非常好.

编辑:我假设在运行中意味着@运行时.如果你只需要它是一个编译时标志,那么Gianni的答案可能最容易实现.日志库为您提供了很大的灵活性,并允许重新配置@ runtime.

  • +1.log4cpp有点旧; 我建议调查log4cxx,其中一个Boost.Log候选者或Pantheios. (2认同)

for*_*tor 5

另一个简单的解决方案涉及在调试模式和非调试模式下打开对std::ostream的引用,如下所示:cout/dev/null

在debug.h中:

extern std::ostream &dout;
Run Code Online (Sandbox Code Playgroud)

在调试.c中

#ifdef DEBUG
std::ostream &dout = cout;
#else
std::ofstream dev_null("/dev/null");
std::ostream &dout = dev_null;
#endif
Run Code Online (Sandbox Code Playgroud)

进而:

dout << "This is a debugging message";
Run Code Online (Sandbox Code Playgroud)

当然,这仅适用于/dev/null指向空设备的任何系统。由于dout这里的引用是全局的,所以它非常喜欢cout. 通过这种方式,您可以将同一个流指向多个输出流,例如日志文件,具体取决于调试标志的值等。