C ++中的转储工具如PHP中的var_dump()?

时间:2009-05-06 10:29:30

标签: php c++

当我在大学时,我做了一些C / C ++,但在不久的将来,我在PHP工作,现在我希望花更多的时间学习C / C ++。

在PHP中,我使用print_r()或var_dump()来显示结构或数组中的数据。我是否在C中有这样的默认功能,以便查看我在结构或数组中有什么用?

6 个答案:

答案 0 :(得分:16)

C ++中没有这样的功能。你当然可以编写自己的Dump()函数。通常无法提供此类功能的原因是C ++编译过程删除了构造转储输出所需的对象元数据。您当然可以在调试器中显示结构内容,其中此类元数据在调试信息中维护。

顺便问一下,你问的是C还是C ++?这两种语言在功能和方法上都有很大的不同,尽管它们都没有var_dump()或类似的。

答案 1 :(得分:6)

C ++本身并没有提供类似var_dump的东西,但是像Boost.Fusion这样的库以及ADAPT_STRUCT和ADAPT_ADT工具很容易实现。

事实上,正如其他回复中所说,C ++编译器不会生成生成此类输出所需的元数据。但是,可以生成这些元数据并使用一些模板元编程来使用它们。

这样我在这里实现了一个adapt_struct_printer,它可以打印std :: container,任何类或结构,boost :: variant和boost :: tuple。

新解决方案

现在您可以轻松执行以下操作:

#include <iostream>
#include <pre/json/to_json.hpp>

struct customer {
  std::string name;
  size_t money_spent;
  std::vector<std::string> interests;
};

BOOST_FUSION_ADAPT_STRUCT(customer,
  name,
  money_spent,
  interests)

...

customer my_customer{
  "Mr. Dupond",
  1000,
  {"sport articles", "food", "tools"}
};

std::cout << pre::json::to_json(my_customer) << std::endl;

你可以使用这个库反向执行from_json来填充json中的结构。

此处提供了一份文档:http://daminetreg.github.io/lib-cpp-pre/html/namespacepre_1_1json.html#a4325d2cdd64a7e321303fd4428f298b9

旧响应

唯一的要求是你在课堂上调用BOOST_FUSION_ADAPT_STRUCT / BOOST_FUSION_ADAPT_ADT(见http://www.boost.org/doc/libs/1_57_0/libs/fusion/doc/html/fusion/adapted.html

这个例子:

#include <iostream>

#include <swissarmyknife/boost/fusion/adapted_struct_printer.hpp>

#include <boost/fusion/include/define_struct.hpp>
#include <boost/variant.hpp>
#include <boost/tuple/tuple.hpp>


namespace bla {

  struct someclass {
     int i = 12;
     int j = 15;
  };

  using boost::fusion::detail::operator <<;
}

BOOST_FUSION_ADAPT_STRUCT(bla::someclass,
  (int, i)
  (int, j)
)

BOOST_FUSION_DEFINE_STRUCT((bla), innerbim,
    (std::string, mystring)
    )

BOOST_FUSION_DEFINE_STRUCT((bla), bimbim,
    (int, boom)
    (int, bam)
    (bla::innerbim, my_inner_bim)
    )


typedef boost::variant<int, double, bla::innerbim> myvariant_t;
typedef boost::tuple<std::string, int, bla::innerbim, myvariant_t> my_tuple_t;


BOOST_FUSION_DEFINE_STRUCT((bla), blabla,
    (bla::bimbim, bim)
    (int, i)
    (int, j)
    (std::vector<double>, list)
    (std::list<bla::bimbim>, list_of_bimbim)
    (my_tuple_t, mytuple)
    (myvariant_t, myvariant)
    )

int main(int argc, char** argv) {
  using namespace swak;

  bla::blabla instance{
    {22, 12, bla::innerbim{"COOL"} }, 
    23,
    43, 
    {2.00, 39.07, 24.05},
    { 
      {24, 9, bla::innerbim{"FEEL GOOD"} },
      {26, 14, bla::innerbim{"SO BAD"} },
    },
    {"Hey that's not an int", 1, bla::innerbim{"hello"}, 12},
    bla::innerbim("I'm in the variant")
  };
  std::cout << instance << std::endl;

  bla::someclass otherinstance{};
  std::cout << "Other instance : " << otherinstance << std::endl;

  return 0;
}

打印出以下内容:

{
    bim :
        {
            boom : 22,
            bam : 12,
            my_inner_bim :
                {
                    mystring : COOL,
                }
        }
    i : 23,
    j : 43,
    list : [2, 39.07, 24.05],
    list_of_bimbim : [    
        {
            boom : 24,
            bam : 9,
            my_inner_bim :
                {
                    mystring : FEEL GOOD,
                }
        }
    ,     
        {
            boom : 26,
            bam : 14,
            my_inner_bim :
                {
                    mystring : SO BAD,
                }
        }
    ],
    mytuple :
        {
            0 (Ss) : Hey that's not an int,
            1 (i) : 1,
            2 (N3bla8innerbimE) :
                {
                    mystring : hello,
                }
            3 (N5boost7variantIidN3bla8innerbimENS_6detail7variant5void_ES5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_EE) : 

                {
                    12}
        }
    myvariant : 

        {

            {
                mystring : I'm in the variant,
            }
        }
}

Other instance :     
    {
        i : 12,
        j : 15,
    }

我正在改进实现,以便在某些时候将其作为boost融合中可能的新功能,但它已经可以使用,如下所示:

https://github.com/daminetreg/lib-cpp-swissarmyknife/blob/feature/adapted_struct_printer_improved/test/adapted_struct_printer.cpp

答案 2 :(得分:1)

这是可能的,但是如果启用了调试符号并且禁用了所有优化,则需要做很多工作。它也会很慢,也许不太可靠[* 1]。

调试器可以执行的任何操作都可以由dump()函数复制,该函数会导致断点和注销信息。

某些调试器可以自动化,因此转储函数本身可能会在调试器中编写。

* 1例如在处理某些断点时,调试器有时会崩溃。例如在尝试转储数据之前,程序需要有一个断点并暂停所有线程。例如需要处理实时中断的程序可能不起作用。例如调试器需要足够可靠以处理许多断点而不会引入其他问题。

答案 3 :(得分:0)

不,您必须使用cout或C样式printf系列输出函数中的一个用于用户定义的数据结构。类似地,对于数组(C风格的字符串除外),您必须遍历所有元素并打印每个元素。

答案 4 :(得分:0)

不,没有。例如,使用ddd之类的调试器。大多数IDE都集成了一个。

答案 5 :(得分:0)

在微软文章中有一些解决方案:

矢量::的push_back

https://msdn.microsoft.com/pt-br/library/7fthz5xd.aspx

template <typename T> void print_elem(const T& t) {
    cout << "(" << t << ") ";
}

template <typename T> void print_collection(const T& t) {
    cout << "  " << t.size() << " elements: ";
    for (const auto& p : t) {
        print_elem(p);
    }
    cout << endl;
}

并呼吁:

cout << "vector data: " << endl;
print_collection(v);