2012-05-19 58 views
0

我已經使用Visual C++ 2008 express爲基於文本的RPG遊戲製作了三個文件。在我真正深入瞭解所有事情之前,我想先弄清楚基礎知識:新遊戲,保存遊戲,繼續遊戲,退出遊戲。到目前爲止,我已經制作了一個角色部分(在這種情況下找到了武器)並退出了所有的遊戲。我被困在如何將武器統計信息從結構傳遞到保存文件。我似乎通過結構的成員沒有問題,並檢查文件來找到「垃圾」:Ì和-858993460代替我的價值觀。使用函數將結構寫入/讀取文件,Visual C++ 2008 express

我應該如何解決我的save_game和continue_game功能?我已經做了大量的研究,試圖弄清楚這一點,我試過的東西似乎沒有幫助。

下面的代碼的重要棋子:

struct player_character 
{ 
char type; 
int damage; 
int stability; 
}; 

void save_game(player_character& pc, ofstream &save); 
void continue_game(player_character& pc, ifstream &get); 

int main() 
{ 
player_character pc; 
ofstream save; 
ifstream get; 

//rest of main() goes here. 

//pause screen 
system("pause"); 
return 0; 
} 

//rest of functions go here. 

void save_game(player_character &pc, ofstream &save_data) 
{ 
save_data.open ("save.dat", ios::binary); 
    if (save_data.is_open()) 
    { 
    save_data << "pc.type = " << pc.type << endl; 
    save_data << "pc.damage = " << pc.damage << endl; 
    save_data << "pc.stability = " << pc.stability << endl; 
       //doesn't work 
    //save_data.write(reinterpret_cast<char*>(&pc), sizeof(pc)); 
    save_data.close(); 
    } 
    else 
    { 
    cout << " Error. Unable to open file."; 
    } 
} 

void continue_game(player_character &pc, ifstream &get_data) 
{ 
get_data.open("save.dat"); 
if (get_data.is_open()) 
    { 
       //doesn't work 
    //get.read(reinterpret_cast<char*>(&pc), sizeof(pc)); 
    get.close(); 
    } 
    else 
    { 
    cout << " Error. Unable to open file."; 
    } 
} 

感謝效應初探。我正在嘗試以下修訂。 continue_game函數似乎正常工作。我沒有收到任何錯誤(尚未)。當我在製作字符後選擇保存時,我收到以下錯誤:Undone.exe中0x69197a28未處理的異常:0xC0000005:訪問衝突讀取位置0xffffffcc。

谷歌顯示它是某種Windows問題。

爲什麼我的函數會導致這個錯誤?

void save_game(ofstream &save, player_character const &pc) 
{ 
save.open ("save.dat"); 
    if (save.is_open()) 
    { 
    save.write(reinterpret_cast<char const *>(pc.type), sizeof pc.type); 
    save.write(reinterpret_cast<char const *>(pc.damage), sizeof pc.damage); 
    save.write(reinterpret_cast<char const *>(pc.stability), sizeof pc.stability); 
    save.close(); 
    } 
    else 
    { 
    cout << " Error. Unable to open file."; 
    } 
} 

int continue_game(ifstream &get) 
{ 
if (!get.read(reinterpret_cast<char *>(&pc.type), sizeof pc.type)) { /* error */ } 
if (!get.read(reinterpret_cast<char *>(&pc.damage), sizeof pc.damage)) { /* error */ } 
if (!get.read(reinterpret_cast<char *>(&pc.stability), sizeof pc.stability)) { /* error */ } 

return pc.type; 
return pc.damage; 
return pc.stability; 
} 

我已經改變了save_game和continue_game代碼,幷包括在這裏了。我還收集了調試器和汽車輸出(汽車的小版本,不是全部7頁)。顯然,我的值並沒有在save_game中進行評估,所以continue_game沒有任何用處,並且不會導致錯誤。

下面的代碼和調試器/汽車打印:

int save_game(ofstream &save, player_character& pc) 
{ 
save.open ("save.dat", ios::binary); 
if (save.is_open()) 
{ 
//the error hits here: 
    save.write(reinterpret_cast<char const *>(pc.type), sizeof pc.type); 
    save.write(reinterpret_cast<char const *>(pc.damage), sizeof pc.damage); 
    save.write(reinterpret_cast<char const *>(pc.stability), sizeof pc.stability); 
    save.close(); 
} 
else 
{ 
    cout << " Error. Unable to open file."; 
} 
return pc.type; 
return pc.damage; 
return pc.stability; 
} 

int continue_game(ifstream &get, player_character& pc) 
{ 
get.open ("save.dat", ios::binary); 
if (get.is_open()) 
{ 
    if (!get.read(reinterpret_cast<char *>(&pc.type), sizeof pc.type)) { /* error */ } 
    if (!get.read(reinterpret_cast<char *>(&pc.damage), sizeof pc.damage)) { /* error */ } 
    if (!get.read(reinterpret_cast<char *>(&pc.stability), sizeof pc.stability)) { /* error */ } 
    get.close(); 
} 
else 
{ 
    cout << " Error. Unable to open file."; 
} 
return pc.type; 
return pc.damage; 
return pc.stability; 
} 

調試器輸出窗口:在Undone.exe在0x644e7a28 第一次機會異常:0000005:訪問衝突讀取位置0xffffffcc。 Undone.exe中0x644e7a28未處理的異常:0xC0000005:訪問衝突讀取位置0xffffffcc。

汽車: - PC {類型= 'I' 損壞= -858993460穩定性= -858993460} player_character & 型-52 'I' 字符 損傷-858993460 INT 穩定性-858993460 INT pc.type -52 'Ì'char - save {_Filebuffer = {...}} std :: basic_ofstream> & + std :: basic_ostream> {...} std :: basic_ostream> + _Filebuffer {_Pcvt = 0x00000000 _Mychar ='Ì '_Wrotesome = false ...} std :: basic_filebuf>


好吧,我設法取得了一些進展。我發現我需要將參數放置在main_menu函數中(請注意,我沒有考慮main()函數,但我做了一個函數),以便將它們傳遞給我的save_game函數。我還能夠通過在我的寫入功能中添加&來阻止訪問錯誤。 所以這個:

save.write(reinterpret_cast<char const *>(&pc.type), sizeof pc.type); 
save.write(reinterpret_cast<char const *>(&pc.damage), sizeof pc.damage); 
save.write(reinterpret_cast<char const *>(&pc.stability), sizeof pc.stability); 

代替:

save.write(reinterpret_cast<char const *>(pc.type), sizeof pc.type); 
save.write(reinterpret_cast<char const *>(pc.damage), sizeof pc.damage); 
save.write(reinterpret_cast<char const *>(pc.stability), sizeof pc.stability); 

的savve_game代碼仍然當涉及到將數據放入一個文件,但它打印輸出到屏幕不能正常工作呢。

+0

您可能不希望混合格式化和未格式化的輸出,並且*絕對*不希望一次性序列化非基元類型。你*有序列化每個成員。 –

+0

請使用調試器,它會告訴你到底是哪一行導致了錯誤。如果您可以向我們顯示導致錯誤的行,我們可以提供更多幫助。順便提一下,讓這個問題變得友好很好。 –

回答

0

它看起來像我想出來的!下面是我想到的:struct in array ...它看起來工作得很好。

void save_game(fstream& file, player_type& pc) 
{ 
    file.open("save.dat"); 
    if (file.is_open()) 
     for (int i = 0; i < 1; i++) 
     { 
      file << pc.w_name << endl; 
      file << pc.d_rate << endl; 
      file << pc.s_rate << endl; 
      file.close(); 
     } 
     else 
      cout << " Error. Unable to open file."; 
    menu(pc); 
}//end save function 

void continue_game(fstream& file, player_type player[]) 
{ 
    file.open("save.dat"); 
    if (file.is_open()) 
     for (int i = 0; i < 1; i++) 
     { 
      file >> player[i].w_name; 
      file >> player[i].d_rate; 
      file >> player[i].s_rate; 
      file.close(); 
     }     
     else 
      cout << " Error. Unable to open file."; 
    for (int i = 0; i < 1; i++) 
    { 
     cout << "You are continuing the game with the following weapon: " << player[i].w_name << endl; 
     cout << "Which has a damage rating of " << player[i].d_rate << " and a stability rating of " << player[i].s_rate << endl; 
    } 
    cout << endl; 
    menu(pc); 
}//end continue_game 
0

您必須逐個讀取和寫入每個基本數據類型,並且只使用未格式化的I/O。示例:

void serialize(std::ostream & o, Player const & p) 
{ 
    o.write(reinterpret_cast<char const *>(p.type), sizeof p.type); 
    o.write(reinterpret_cast<char const *>(p.damage), sizeof p.damage); 
    o.write(reinterpret_cast<char const *>(p.stability), sizeof p.stability); 
} 

Player deserialize(std::istream & i) 
{ 
    Player p; 
    char pt; 
    int pd, ps; 

    if (!i.read(reinterpret_cast<char *>(&pt), sizeof pt)) { /* error */ } 
    if (!i.read(reinterpret_cast<char *>(&pd), sizeof pd)) { /* error */ } 
    if (!i.read(reinterpret_cast<char *>(&ps), sizeof ps)) { /* error */ } 

    p.type = pt; p.damage = pd; p.stability = ps; 
    return p; 
} 
+0

我不明白你爲什麼必須逐一讀寫每一個原始數據類型,一次讀寫結構應該可以正常工作,即'o.write(reinterpret_cast (&p),sizeof p);' 。 –

+0

@JesseGood:雖然不便攜。 –

0

對上一個答案和已編輯問題的跟進。

你continue_game署名判定,

int continue_game(ifstream &get) 

PC必須是某種形式保存你試圖恢復具有全球性結構體。如果pc在運行時被分配,那麼你使用不正確。

當你這樣做:

return pc.type; 
    return pc.damage; 
    return pc.stability; 

一個函數只能有一個返回類型;只有pc.type會被返回。這不是錯誤的原因,而是您應該注意的設計缺陷。

你最初的方法continue_game,其中你在相關的結構類型作爲參數傳遞,

void continue_game(player_character &pc, ifstream &get_data) 

是一個更好的主意。我相信,如果你將兩者結合起來,你會發現自己沒有錯誤。

如果錯誤仍然存​​在,請使用調試器並粘貼該行。另外,如果您願意,我可以提供我描述的代碼樣本。

+0

你想讓我發佈整個代碼頁嗎?它具有結構和我用來設計角色以及save_game和continue_game函數的所有功能。對於所有我知道這是我的其他功能在頁面上傳遞糟糕的代碼到我的保存功能。 –