C ++中的变量转储

时间:2009-04-11 13:53:44

标签: c++ data-structures

是否有可能在复杂的结构甚至是C ++中的数组上进行“转储”,以便在视觉上能够检查它们内部的内容?

我正在考虑类似于PHP中的print_r()或var_dump()。

干杯, -fin

7 个答案:

答案 0 :(得分:8)

简短的回答是:不,除非你自己手动编写这样的例程。

这通常不是一个坏主意,但如果您经常添加/更改成员,它通常会遇到与课程不同步的问题。这是不可避免的,因为C ++缺乏对struct的任何形式的内省。

如果您决定采用这种方式,最好的办法是为std::ostream& operator<<(std::ostream& os, MyClass const&)编写一个重载,这样就可以将您的类打印到任何IOStreams输出流。

答案 1 :(得分:4)

通常调试人员足够聪明,可以做到这一点。

在GDB中,您可以使用:

print structure

在NTSD中你可以做超级酷炫的事情:

dt -r structure

如果您只是将其用于调试目的,我强烈建议您学习使用调试器。即使你想要记录它的东西(即打印数十亿次),你也可以设置一个断点宏。

在NTSD中:

bp yourdll!yourobject::yourfunction "dt -r structure;g"

我确信有一种方法可以在GDB中实现

答案 2 :(得分:3)

除了其他答案之外,根据您的需要以及是否关心可移植性,您可以从编译器生成的调试信息中获取所需的信息。您可以从构建中解析COFF / ELF /任何格式文件,这将为您提供计算对象中变量名称和类型所需的信息。

答案 3 :(得分:3)

如果向C ++添加反射(使用第三方库或供应商扩展),则可以编写例程以使用该反射数据来转储任意结构。例如,我有一些代码使用CERN的Reflex库迭代一个类或结构的成员并将它们转储到YAML

答案 4 :(得分:1)

在C ++中通常不可能,因为它需要使用C ++没有的反射。您当然可以编写自己的函数来转储特定的数据结构。

答案 5 :(得分:0)

实际上,在您可以使用gdb并且在启用调试符号的情况下编译源代码的环境中(例如-ggdb),您可以使用调试器(例如,当您需要图形化时,可以使用命令行中的gdb或ddd)。

考虑这段代码:

#include <string>
#include <vector>

struct test
{
    int a;
    float b;
    std::string c;
};

int main()
{
    std::vector<int> v;

    test t;
    t.a=1;
    t.b=2.0;
    t.c="hello there";


    return 0;
}

当礼貌地询问gdb时,它可以给我以下输出:

(gdb) break 20
Breakpoint 1 at 0x8048622: file bla.cpp, line 20.
(gdb) run
Starting program: /home/edb/a.out 

Breakpoint 1, main () at bla.cpp:21
21      return 0;
(gdb) print t
$1 = {a = 1, b = 2, c = {static npos = 4294967295, 
    _M_dataplus = {> = {> = {}, }, _M_p = 0x96b6014 "hello there"}}}
(gdb) ping v
Undefined command: "ping".  Try "help".
(gdb) print v
$2 = { >> = {
    _M_impl = {> = {> = {}, }, _M_start = 0x0, _M_finish = 0x0, 
      _M_end_of_storage = 0x0}}, }

编辑:请注意,此数据可从调试器上下文获得,为了在运行时生成这些转储,您需要预见自己的转储/格式化功能,通常通过重载&lt;&lt; C ++中的operator。

答案 6 :(得分:0)

为什么不使用二进制文件? fstream具有二进制模式,您可以转储除struct,class,namespace或STL列表(如矢量,队列)之外的任何类型。 想将struct,class,namespace(或STL list)转储为二进制文件?创建一个函数,并将每个变量转储到文件中!结束!那不会那么难...... 但想要更多帮助?请参阅此代码段!

#include <iostream>
#include <fstream>//ofstream,ifstream
using namespace std;
ifstream myBdumpin ("data.bin"/*filename*/, ios::in);//ifstream = input
ofstream myBdumpout ("data.bin"/*filename*/, ios::out);//ofstream = output
int main()
{
    char a[8]="Binary!"
    myBdumpout << a;
    char b[8];
    myBdumpin >> b;
    if(a == b)cout << "It worked!" << endl;
    else cout << "It failed..." << endl;
    return 0;
}

它应该有用......