0

私は小さなゲームをしていて、プレーヤーの詳細をtxtファイルに保存しています。そのtxtファイルの例:

Eric 13 8 10 10 30 10 10 50 0 0 0 0
William 1 0 10 30 30 10 10 50 0 0 0 0
John 1 0 10 30 30 10 10 50 0 0 0 0

これは私が念頭に置いていたものです。プレイヤーがプレイ中にゲームを保存することを選択した場合、save_game関数は保存されたデータがすでにあるかどうかをチェックする必要があります。ある場合は、txtの最後にデータを追加する代わりに、overwriteその特定の行にする必要があります。

これが私の現在の機能です:

// SAVE GAME
void save_game(Player player)
{
    ofstream coutfile (SaveDestiny, ios::app);

    if (coutfile.is_open()) // if it opens correctly
    {
        // Now checking if the name already exists
        string imported_name;

        ifstream cinfile (SaveDestiny); // opens file that contains the saved games

        cinfile >> imported_name; // getting first element of file

        bool j = 0; // j = 0 while the strings don't match. j = 1 when the string was found

        while (cinfile >> imported_name) // while the end of file is not reached
        {
            if (player.name.compare(imported_name) == 0) // if the strings are the same, overwrite data
            {
                j = 1;

                coutfile << "                                                                         \r" << endl;
                break;
            }
            else // if the strings are different, keep reading
            {
                cinfile >> imported_name;
            }
        }

        // Continuing...
        coutfile << player.name << " " << player.level << " " << player.exp << " " << player.max_exp << " "
            << player.hp << " " << player.max_hp << " " << player.mp << " " << player.max_mp << " "
            << player.gold << " " << player.weapon << " " << player.shield << " " << player.heal_spell << " "
            << player.attack_spell << endl;
    }
    else
    {
        ofstream coutfile (SaveDestiny, ios::app);
        coutfile << "test";
        cout << "Unable to open file";
        cin.get();
    }

    draw_rectangle(37,8,72,14,15);  // white limits
    draw_rectangle(39,9,70,13,9);   // blue background
    cor(9,15);
    gotoxy(50,10);
    cout << "GAME SAVED!";
    gotoxy(41,12);
    cor(9,14);
    cout << "Press <Enter> to continue... ";
    cin.get();
}
4

2 に答える 2

3

最近のほとんどのファイルシステムでは、ファイルは「行ベース」(または「レコードベース」)ではなく、文字ベースであるため、「行を上書き」することはできません。古い行の長さは20文字、新しい行の長さは24文字になる可能性があります。その場合、古い行次の行の最初の4文字が上書きされます。これを機能させるには、ファイルの後半の行の後にすべてを「プッシュ」する必要があります。これは、C ++(またはC)IO機能では不可能です。

1つのオプションは、すべての行を固定長、たとえば50文字で書き込むことです。これにより、3行目を上書きするには、実際には24文字しか必要ない場合でも、100から149文字を置き換える必要があります。

もう1つのオプションは、ファイルをレコードベースの形式でメモリに保持し、ファイルを変更するたびにファイル全体を書き出すことです(または、少なくとも新しい行とそれに続くすべての行を書き出す)

于 2013-03-02T01:16:18.193 に答える
0

さて、私は問題を回避することができました、そして今それは見事に働いています!:D

まず、functionプレーヤー名がすでににあるかどうかを確認しますtxt。イネーブル変数を作成しましたj。の場合、名前が存在し、データは!j=1である必要があります。overwrittenの場合j=0、関数はappendすぐにデータをtxtに送信します。

わかりました、としましょうj=1。この関数は、の行数を決定しtxtます。vector次に、内部に2つのベクトルを持つを作成します:、、nameおよびgame variables。その後、関数はtxtファイルの以前のコンテンツを削除します。そして、関数の最後に新しいデータが書き込まれるため、txt上書きする必要のあるデータを除いて、ベクトルの内容をに書き込みます(その部分のへの書き込みはスキップされます)。txt:DI私が自分自身を十分に明確にしたことを願っています。誰かが私が書いたものを理解していない場合は申し訳ありません...

これが私の新しいsave_game関数です:

// SAVE GAME
void save_game(Player player)
{
    ofstream coutfile (SaveDestiny, ios::app);

    if (coutfile.is_open()) // if it opens correctly
    {
        string imported_name;
        ifstream cinfile (SaveDestiny); // opens file that contains the saved games

        bool j = 0;

        // Now checking if the name already exists
        while (cinfile >> imported_name) // while the end of file is not reached
        {
            if (player.name.compare(imported_name) == 0) // if the strings are the same, overwrite data
            {
                j = 1; // enable overwrite
                break;
            }
            // if the strings are different, keep reading
        }
        // at this point: j = 0 to append to end. j = 1 to overwrite.

        // Overwriting data
        if (j == 1)
        {
            ifstream cinfile (SaveDestiny);

            // now determining the size of the vector (number of lines in txt)
            int line_numbers = 0;
            string line;
            while (getline(cinfile, line))
            {
                line_numbers++;
            }

            cinfile.close();    // closing
            ifstream cinfile2 (SaveDestiny);    // reopening to read from the beginning 

            // now creating the vector with the saves
            vector<vector<string>> temp_saves(line_numbers, vector<string>(2));
            string name2;
            string values;

            for (unsigned int x = 0; x < temp_saves.size(); x++)
            {
                cinfile2 >> name2;
                getline(cinfile2, values);

                temp_saves[x][0] = name2;
                temp_saves[x][1] = values;
            }

            coutfile.close(); // closing output file
            ofstream coutfile2 (SaveDestiny); // reopening in overwrite mode

            // delete all saves.txt, copying vector content to txt (except the one we want to overwrite)
            for (unsigned int x = 0; x < temp_saves.size(); x++)
            {
                if ( temp_saves[x][0].compare(player.name) != 0)
                {
                    coutfile2 << temp_saves[x][0] << temp_saves[x][1] << endl;
                }
            }
            coutfile2.close(); // closing output file
        }

        // Appending new data...
        ofstream coutfile3 (SaveDestiny, ios::app); // reopening in append mode
        coutfile3 << player.name << " " << player.level << " " << player.exp << " " << player.max_exp << " "
            << player.hp << " " << player.max_hp << " " << player.mp << " " << player.max_mp << " "
            << player.gold << " " << player.weapon << " " << player.shield << " " << player.heal_spell << " "
            << player.attack_spell << endl;
    }
    else
    {
        ofstream coutfile (SaveDestiny, ios::app);
        cout << "Unable to open file";
        cin.get();
    }

    draw_rectangle(37,8,72,14,15);  // white limits
    draw_rectangle(39,9,70,13,9);   // blue background
    cor(9,15);
    gotoxy(50,10);
    cout << "GAME SAVED!";
    gotoxy(41,12);
    cor(9,14);
    cout << "Press <Enter> to continue... ";
    cin.get();
}
于 2013-03-02T15:15:56.717 に答える