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 工具是不可能的。

一种选择是以固定长度写入所有行,例如 50 个字符,以便覆盖第 3 行涉及替换字符 100 到 149,即使该行实际上只需要 24 个字符。

另一种选择是将文件以基于记录的形式保存在内存中,并在每次更改时写出整个文件(或至少写出新行和之后的所有行)

于 2013-03-02T01:16:18.193 回答
0

好的,我已经设法解决了这个问题,现在它工作得很好!:D

首先,function检查玩家姓名是否已经在txt. 我创建了一个启用变量j。什么时候j=1,名字存在,数据需要overwritten!当 时j=0,该函数将append数据立即写入 txt。

好吧,让我们说j=1。该函数确定txt. 然后它创建一个vector内部有两个向量:namegame 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 回答