0

テキストベースのRPGゲーム用にVisualC++2008Expressを使用して3つのファイルを作成しました。本当にすべてに飛び込む前に、基本を理解したいと思います。新しいゲーム、ゲームの保存、ゲームの続行、ゲームの終了です。これまでのところ、キャラクターセクションを作成し(この場合は武器を見つけます)、ゲームを終了します。武器の統計を構造体から保存ファイルに渡す方法に固執しています。構造体のメンバーを問題なく渡し、ファイルをチェックして、値の代わりに「ジャンク」:Ìと-858993460を見つけたようです。

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。

Googleはそれをある種の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での初回例外:0xC0000005:アクセス違反の読み取り場所0xffffffcc。Undone.exeの0x644e7a28で未処理の例外:0xC0000005:アクセス違反の読み取り場所0xffffffcc。

自動車:-pc {type='Ì'damage=-858993460stable = -858993460} player_character&type-52'Ì'chardamage -858993460 int stable -858993460 intpc.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コードは、データをファイルに入れる場合はまだ正しく機能しませんが、画面に出力されます。

4

3 に答える 3

0

各プリミティブデータ型を1つずつ読み書きし、フォーマットされていない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;
}
于 2012-05-19T23:50:12.707 に答える
0

前の回答と編集された質問へのフォローアップ。

continue_gameの署名から判断すると、

int continue_game(ifstream &get)

pcは、再開しようとしている文字を保持する何らかの形式のグローバル構造体である必要があります。PCが実行時に割り当てられている場合は、誤って使用しています。

これを行うとき:

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

関数は1つのreturn-typeのみを持つことができます。pc.typeのみが返されます。これはエラーの原因ではなく、注意が必要な設計上の欠陥です。

継続への最初のアプローチ。関連する構造体をパラメーターとして渡した場合、

void continue_game(player_character &pc, ifstream &get_data) 

はるかに良いアイデアでした。この2つを組み合わせると、エラーが発生することはないと思います。

エラーが続く場合は、デバッガーを使用して行を貼り付けてください。さらに、必要に応じて、説明したコードのサンプルを提供できます。

于 2012-05-21T04:33:19.220 に答える
0

わかったみたいですね!これが私が思いついたものです:配列内の構造体...そしてそれはうまく機能しているようです。

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
于 2012-06-02T07:00:27.707 に答える