2009-04-11 10 views
4

複雑な構造やC++の配列であっても、それらの内部に何が入っているのかを視覚的に確認するために 'ダンプ'することはできますか?C++の変数ダンプ

私はPHPのprint_r()やvar_dump()と似たようなものを考えています。

乾杯、

C++で一般に不可能

答えて

1

-Fin それはC++が持っていない反射の使用を必要とします。もちろん、特定のデータ構造をダンプする独自の関数を書くことができます。

8

短い答えは:いいえ、手作業でこのようなルーチンを手書きで書くのでない限りです。

多くの場合、悪い考えではありませんが、頻繁にメンバーを追加/変更する場合、クラスとの同期が外れるという通常の問題があります。これは、C++にはstructにイントロスペクションの形式がないため、やむを得ないことです。

このようにする場合は、std::ostream& operator<<(std::ostream& os, MyClass const&)のオーバーロードを書き込むことをお勧めします。これにより、クラスをIOStreamsの出力ストリームに出力することができます。

+0

オペレータを供給して唯一の問題は、<<()、それは一種の)(>>演算子を意味し、この場合には、それはおそらくない、存在していることです。私はDumpOn(ostream&os)という名前の関数を好む。 –

+0

@Neil:まあ、私はそれがそれを意味することに同意しますが、私はあなたの意見を見ます。演算子>>()の実装はいつもより難しいので、私はしばしば気にしませんが、持っていることはいつもいいです。 –

+0

他の問題は、フォーマットされた出力メソッド(op <<)とロー・ダンプ・メソッドを持つことが珍しいことではないということです。この場合、名前付きアプローチはより一貫性があります。 –

3

その他の回答に加えて、必要な情報や移植性を気にするかどうかによって、コンパイラが生成するデバッグ情報から必要な情報を得ることができます。ビルドからCOFF/ELF /任意の書式ファイルを解析することができます。これにより、オブジェクト内の変数の名前と型を計算するのに必要な情報が得られます。

3

C++にリフレクションを追加する場合(サードパーティのライブラリまたはベンダー拡張を使用)、そのリフレクションデータを使用して任意の構造をダンプするルーチンを作成できます。たとえば、CERNのReflexライブラリを使用してクラスまたは構造体のメンバーを反復処理し、にダンプするコードがあります。

4

通常、デバッガはこれを行うのに十分スマートです。

print structure 

をし、NTSDにあなたはユーバークール行うことができます:

GDBでは、使用することができます

dt -r structure 

あなただけのデバッグ目的のためにこれを使用している場合、私は非常にお勧めの学習をデバッガを使用します。あなたが何か(たとえ何百回も印刷する)でログしたいものであっても、ブレークポイントマクロを設定することができます。

NTSDで

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

そして、私はあなたがあなたの処分でGDBを持っている環境では、

0

実際にもGDBでそれを行う方法があると確信していると、あなたのコンパイルデバッグシンボルを有効にしたソース(たとえば-ggdb)を使用すると、デバッガを使用することができます(例えば、グラフィカルに必要なときにコマンドラインまたはdddからgdbを実行します)。

は、コードのこの部分を考えてみましょう:GDBを尋ねるとき

#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) 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}}, } 

編集:ため、デバッガのコンテキストからこのデータが利用可能であることに注意を実行時にこれらのダンプを生成するには、通常はC++で< <演算子をオーバーロードすることによって行われる、独自のダンプ/フォーマッティング機能を予期する必要があります。

0

なぜバイナリファイルを使用しないのですか? fstreamにはバイナリモードがあり、struct,class,namespaceまたはSTLリスト(vector、queueなど)以外のすべてのタイプをダンプすることができます。 構造体、クラス、名前空間(またはSTLリスト)をバイナリにダンプしますか?関数を作り、各変数をファイルにダンプしてください!終わり!それは難しいことではありません... しかし、より多くのヘルプが欲しいですか?このコードスニペットを参照してください!

#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; 
} 

それが動作するはずです...

関連する問題