2013-11-28 145 views
0

我創建了兩個函數來保存和加載一個對象到程序中。ifstream無法讀取

保存功能aparently成功保存對象:

void Game::SaveGame() 
{ 
std::string filename = "saves/miner-save-" + currentDate() + ".gem"; 

std::ofstream outfile; 
outfile.open(filename.c_str(), std::ios::binary); 

outfile.write((char *)(&myGame), sizeof(Game)); 

if (outfile.fail()) 
    std::cout << "write failed" << std::endl; 

outfile.close(); 

std::cout << myGame->myMiner->getX(); //debug purposes : prints 25 

} 

的問題似乎是在負載功能,因爲從所讀取的對象的整數返回的值是不正確。

void Game::LoadGame() 
{ 

    ..some code.. 

    std::string filename = GetLoadFilename(nameID); //works 

    std::ifstream infile; 
    infile.open(filename, std::ios::binary); 

    infile.read((char *)&myGame, sizeof(Game)); 

    if (infile.fail()) 
    { 
     std::cout << "read failed" << std::endl; 
    } 

    std::cout << myGame->myMiner->getX(); //debug purposes : prints -842150451 

    Play(myGame->myMiner->getX(), myGame->myMiner->getY()); 
} 

類遊戲:

class Game { 

    Game *myGame; 
    Miner *myMiner; 
    BlockTypes *myBlockTypes; 
    //Block* myBlocks[10000]; 
    Consola *myConsole; 
    Mine *myMine; 
    int linhas, colunas; 
    int _currentStatus; 

    public: 
    ..some functions such as load & save 
}; 

加載時,總是顯示 「讀取失敗」 的消息,什麼是錯?

+0

沒有看到「遊戲」的定義,很難說明原因。我會說保存一個'struct'或'class'的二進制圖像只有當它是一個沒有指針的POD類型時纔會工作。即便如此,這並不是最強大的做事方式。 (它通常會跨越平臺,例如,在許多情況下,包括32位和64位x86之間,取決於結構的內容。) –

+0

嗯,我已經添加了遊戲信息。基本上有更好的方法來保存類文件中的所有數據嗎? – xRed

+3

是的,使用'write'和'read'完全不適用於這種結構。 :-)這些指針將無效,並且不會保存指向的數據。你會想查找_serialization的主題._ Boost有一個序列化庫,儘管我從來沒有使用它。看這裏:http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/index.html 否則,你將不得不寫一些自定義的行爲結構和存儲它,以及一些東西其他自定義,讀取您存儲的內容並創建/填充新結構。 –

回答

1

使用指針寫入結構會寫入指針的值,而不是指向對象的值。 你需要看看序列化。序列化是一種將數據結構化到連續非結構化介質(如硬盤驅動器)的方法。即,如何將你的信息結構化爲一行位,這樣你就可以從同一行位重構你的對象。以前連接的增強庫是一個選項,但也有XMLJSONother solutions,你應該檢查。

0

一般的方法是使用「infile >> myGame」。在Game類中,定義運算符< <和運算符>>以覆蓋爲您的Game類自定義的默認值。

這些函數通常對類的每個成員都有一個>>或< <的列表(如果不定義運算符,這是默認值)。但是你需要做出一些決定併爲指針類型成員編寫一些代碼。內存中對象的位置將從運行轉移到運行,因此您不能保存並加載指針值。例如,也許在Game ::運營商< <您需要在myMine上調用< <來轉儲它(深層複製)。但也許Miner是一個指向一個數組的指針,它被單獨保存和加載,所以Game :: operator < <保存了一個礦工ID號或者名稱字符串,Game運算符>>使用保存的數據查找Miner以獲取指針。