2009-04-11 94 views
4

是否有可能對複雜結構甚至C++數組執行「轉儲」,以便直觀地檢查出它們裏面的內容?C++中的變量轉儲

我正在考慮類似於PHP中的print_r()或var_dump()。

乾杯, -fin

回答

1

一般不可能在C++中,因爲它需要使用反射,其C++所沒有的。您當然可以編寫自己的函數來轉儲特定的數據結構。

8

簡短的回答是:不,你自己手動編寫這樣的程序。

這通常不是一個壞主意,但如果您經常添加/更改成員,那麼它通常會遇到與課程不同步的問題。這是不可避免的,因爲C++缺乏對struct的任何形式的自省。

如果你決定這樣做,最好的辦法是編寫一個std::ostream& operator<<(std::ostream& os, MyClass const&)的重載,這將使您的類可以打印到任何IOStreams輸出流。

+0

與供應運營商唯一的問題<<()是它那種意味着運營>>()存在,在這種情況下,它可能不會。我更喜歡命名的DumpOn(ostream&os)函數。 – 2009-04-11 14:03:14

3

除了其他答案之外,根據您的需要以及您是否關心可移植性,您可能會考慮從編譯器生成的調試信息中獲取所需的信息。您可以從構建中解析COFF/ELF /格式文件,併爲您提供所需的信息,以確定對象中變量的名稱和類型。

3

如果向C++(使用第三方庫或供應商擴展)添加反射,則可以編寫例程以使用該反射數據來轉儲任意結構。例如,我有一些代碼使用CERN的Reflex庫來遍歷類或結構的成員,並將它們轉儲到YAML

4

通常調試器足夠聰明來做到這一點。

在GDB你可以使用:

print structure 

和NTSD你可以做超酷:

dt -r structure 

如果你僅僅使用這個調試目的,我強烈建議學習使用調試器。即使你想記錄你的東西(即打印數十億次),你也可以設置一個斷點宏。

在NTSD:

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

而且我敢肯定是有辦法做到這一點的GDB以及

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

編輯:請注意,這個數據可以從一個調試器背景下,在運行時生成這些轉儲文件時,您需要預見自己的轉儲/格式化功能,通常通過在C++中重載運算符來完成。

0

爲什麼不使用二進制文件? fstream有二進制模式,您可以轉儲除struct,class,namespace或STL列表(如向量,隊列)之外的任何類型。 想要轉儲結構,類,名稱空間(或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; 
} 

它應該工作...