【问题标题】:Printing detailed debugging output easily?轻松打印详细的调试输出?
【发布时间】:2009-01-21 18:48:13
【问题描述】:

我基本上是在寻找一种自动输入以下内容的方法:

cout << "a[" << x << "][" << y << "] =\t" << a[x][y] << endl;

类似:

PRINTDBG(a[x][y]);

理想情况下,这也适用于

PRINTDBG(func(arg1, arg2));

甚至

PRINTDBG(if(condition) func(foo););

(将打印例如“if(false) func(5)”)。

也欢迎非便携式黑客 :)

(不,使用调试器不一样,它的灵活性要低得多,我觉得它很混乱)

【问题讨论】:

    标签: c++ debugging


    【解决方案1】:

    按照您想要的方式,这是不可能的。如果你有 if(condition) func(foo); 给一个宏,它可以将这些东西字符串化,它会打印 if(condition) func(foo); ,但不是用变量的实际值代替。请记住,预处理器不知道该代码的结构。

    为了调试,我会使用一些类型安全的 printf 变体,例如 boost.format 或一些自制的 printf with boost.fusion,这使得打印类似的东西变得更加容易:

    dprintf("a[%][%] = %", (x, y, a[x][y]));
    

    【讨论】:

    • 谢谢。我希望你喜欢它。如果您担心性能(1000000 次迭代大约慢 300 毫秒,而 printf 只需要 40 毫秒),您可以将此优化版本用于 char*:codepad.org/8ZQvdoMq。它收集字符,并一次性写入它们。然后只需要 70 毫秒 :)
    • 它另外使用了一个结构,以避免再次传递结束迭代器,只是为了传递它的类型。但在这里,它只是一个游戏,因为你用它来调试,时间并不重要。但也许你也决定将它用于其他东西。玩得开心:)
    【解决方案2】:

    这是printf样式输出可以更简洁的地方:

    cout << "a[" << x << "][" << y << "] =\t" << a[x][y] << endl;
    printf("a[%d][%d] =\t%d\n", x, y, a[x][y]);
    

    当然,这有只适用于printf 理解的类型的限制,它仍然不能解决您的问题。

    我感觉 Boost 中的表达式分解技术可能有一些价值,但我不是一个模板忍者来识别什么。

    更新:以下内容几乎解决了您的问题:

    #define PRINTDBG(x) cout << #x << " =\t" << x << endl;
    

    但是,当用作PRINTDBG(a[x][y]) 时,它会按字面意思打印:

    a[x][y] = 5
    

    它没有给出x 和y 的实际值。

    【讨论】:

      【解决方案3】:

      我通常使用简单但可自定义的记录器函数而不是宏

      
      Log(const char *format, ...)
      {
          char buffer[MAX_BUFFER_SIZE];
          va_list args;
      
          //get arguements into a list
          va_start(args, format);
      
          //printf formated arguement into a string
          vsnprintf(buffer, sizeof(buffer), format, args);
      
          va_end(args);
      
          printf("%s", buffer);
        }
      

      所以现在你可以做

      Log("a[%d][%d] =\t%d\n", x, y, a[x][y])
      Log("if(%s) func(%d) ;", (condition) ? "true" : "False", func(foo))

      在函数 Log() 中添加一些记录类型(即 LOG_SCREEN、LOG_FILE),现在您可以控制记录到的位置

      添加一些日志记录级别(即 WARN、CRIT)来控制它的显示方式、颜色等。

      当然有很多很多的图书馆已经在做所有这些类型的事情了

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        在与 Greg 的帖子不同的方向略有扩展,我看到了一些不错的 C 程序,看起来像这样

        #DEFINE DEBUG_MODE 1
        //...
        if( DEBUG_MODE)
          printf("methodX() says: y=%i, var1=%i", y, var1);
        

        不过,您的程序中仍有大量 printf,但至少您可以在需要时将它们全部打开和关闭。

        【讨论】:

          【解决方案5】:

          您可以为自定义类定义运算符«,因此您只需定义一次格式:

          struct point3 {
                int x,y,z;
                point3(int a, int b, int c){x=a;y=b;z=c;}
          };
          
          std::ostream& operator << (std::ostream& os, const point3& f) {
                return os << "(" << f.x << "," << f.y << "," << f.z << ")";
          }
          
          point3 p(1,2,3);
          std::cout << p; // prints "(1,2,3)"
          

          这与将 cout 或 clog 重定向到文件非常匹配(不记得 std::clog 是如何工作的)

          #include <iostream>
          #include <fstream>
          
          int main() {
                std::ofstream file("log.txt");
                std::streambuf *filebuf = file.rdbuf();
                std::cout.rdbuf(filebuf);
          
                std::cout << "This is written to the file";
          
                filestr.close();
                return 0;
          }
          

          【讨论】:

            猜你喜欢
            • 2012-01-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-22
            • 1970-01-01
            • 2012-07-06
            • 2015-04-27
            • 2010-12-06
            相关资源
            最近更新 更多