0

first of all I am a beginner in coding. Here is a short TEXT RPG I made. This code worked when std::string strPlayerName; were char* strPlayerName[30]; So after I changed this code regarding to std::string, errors occur. I guess file input/output functions are somewhat wrong. Please give me some corrections!

main function is just tons of switches so I didn't write on.

#include <iostream>
#include <fstream>
#include <string>

class Player
{
private:
    std::string strPlayerName;
    int nSaveNum;
    int nDamage;
    int nHP;
    int nGold;
public:
    Player() = default;
    Player(std::string pName, int Class, int Damage, int HP, int Gold)
        : strPlayerName(pName),nSaveNum(Class), nDamage(Damage), nHP(HP), nGold(Gold)
    {
    }
    Player(const Player& T)
    {
        strPlayerName = T.strPlayerName;
        nSaveNum = T.nSaveNum;
        nDamage = T.nDamage;
        nHP = T.nHP;
        nGold = T.nGold;
    }
    void setName(std::string pName) { strPlayerName = pName; }
    void setSaveNum(int num) { nSaveNum = num; }
    void setDamage(int Damage) { nDamage = Damage; }
    void setHP(int HP) { nHP = HP; }
    void setGold(int Gold) { nGold = Gold; }
    void setBattleGold(int Gold) { nGold += Gold; }
    void setStoreDamage(int HP) { nHP += HP; }
    void setStoreHP(int HP) { nHP += HP; }
    void setStoreGold(int Gold) { nGold -= Gold; }
    std::string getName() const { return strPlayerName; }
    int getSaveNum() const { return nSaveNum; }
    int getDamage() const { return nDamage; }
    int getHP() const { return nHP; }
    int getGold() const { return nGold; }
    void addCharacter()
    {
        std::cout << "NAME : ";
        std::cin >> strPlayerName;
        std::cout << "NUMBER : ";
        std::cin >> nSaveNum;
        nDamage = 5;
        nHP = 100;
        nGold = 0;
    }
    void showPlayer() const
    {
        std::cout << strPlayerName << " / " << nSaveNum << " / " << nDamage << " / " << nHP << " / " << nGold << std::endl;
    }
};

class Monster
{
private:
    std::string strMonsterName;
    int nDamage;
    int nHP;
    int nGold;
public:
    Monster(std::string pName, int Damage, int HP, int Gold)
        : strMonsterName(pName), nDamage(Damage), nHP(HP), nGold(Gold)
    {
    }
    void setHP(int HP) { nHP = HP; }
    std::string getName() const { return strMonsterName; }
    int getDamage() const { return nDamage; }
    int getHP() const { return nHP; }
    int getGold() const { return nGold; }
    void showMonster() const
    {
        std::cout << strMonsterName << " / " << nDamage << " / " << nHP << " / " << nGold << std::endl;
    }
};

void newCharacter(Player& player)
{
    std::ofstream outFile;
    outFile.open("Save.dat", std::ios::binary | std::ios::app);
    player.addCharacter();
    outFile.write(reinterpret_cast<char*>(&player), sizeof(Player));
    outFile.close();
}

Player selectCharacter(int n)
{
    Player player, tmp;
    std::ifstream inFile;
    inFile.open("Save.dat", std::ios::binary);
    if (!inFile)
    {
        throw "File could not be open...";
    }
    inFile.seekg(0, std::ios::beg);
    while (inFile.read(reinterpret_cast<char*>(&player), sizeof(Player)))
    {
        if (player.getSaveNum() == n)
        {
            tmp.setName(player.getName());
            tmp.setSaveNum(player.getSaveNum());
            tmp.setHP(player.getHP());
            tmp.setDamage(player.getDamage());
            tmp.setGold(player.getGold());
        }
    }
    inFile.close();
    std::cout << "Selection Complete" << std::endl;

    return tmp;
}

void showAll()
{
    Player player;
    std::ifstream inFile;
    inFile.open("Save.dat", std::ios::binary);
    if (!inFile)
    {
        std::cout << "File could not be open...";
        return;
    }
    std::cout << "CHARACTER LIST" << std::endl;
    while (inFile.read(reinterpret_cast<char*>(&player), sizeof(Player)))
    {
        player.showPlayer();
    }
    inFile.close();
}
void saveCharacter(Player& p, int n)
{
    bool found = false;
    Player player;
    std::fstream File;
    File.open("Save.dat", std::ios::binary | std::ios::in | std::ios::out);
    if (!File)
    {
        std::cout << "File coud not be open...";
    }
    while (!File.eof() && found == false)
    {
        File.read(reinterpret_cast<char*>(&player), sizeof(Player));
        if (player.getSaveNum() == n)
        {
            player.setName(p.getName());
            player.setSaveNum(p.getSaveNum());
            player.setHP(p.getHP());
            player.setDamage(p.getDamage());
            player.setGold(p.getGold());

            int pos = (-1) * static_cast<int>(sizeof(Player));
            File.seekp(pos, std::ios::cur);
            File.write(reinterpret_cast<char*>(&player), sizeof(Player));
            std::cout << "Save Updated";
            found = true;
        }
    }
}

void delete_character(int n)
{
    Player player;
    std::ifstream inFile;
    std::ofstream outFile;
    inFile.open("Save.dat", std::ios::binary);
    if (!inFile)
    {
        std::cout << "File could not be open...";
        return;
    }
    outFile.open("Temp.dat", std::ios::binary);
    inFile.seekg(0, std::ios::beg);
    while (inFile.read(reinterpret_cast<char*>(&player), sizeof(Player)))
    {
        if (player.getSaveNum() != n)
        {
            outFile.write(reinterpret_cast<char*>(&player), sizeof(Player));
        }
    }
    inFile.close();
    outFile.close();
    remove("Save.dat");
    rename("Temp.dat", "Save.dat");
    std::cout << "Record Deleted" << std::endl;
}
KIN Game
  • 11
  • 1
  • 2
    `inFile.read(reinterpret_cast(&player), sizeof(Player)))` -- This will not work with `std::string` as a member. Neither will writing this way work. The `Player` is no longer trivially-copyable. – PaulMcKenzie Feb 26 '21 at 07:18
  • Please learn how to create a [mcve], with emphasis on the *minimal* part. – Some programmer dude Feb 26 '21 at 07:21
  • how do I copy Player in files? – KIN Game Feb 26 '21 at 07:22
  • Also, if you knew nothing except what `sizeof(Player)` meant, it will be obvious why those calls will not work. The `sizeof(Player)` is a compile-time value -- it never changes. Let's say that `sizeof(Player)` is 32. What if one of those names is 1000 characters -- how will `read` (or `write`) magically know that there are at least 1000 bytes of information to read or write if you're giving it `sizeof(Player)`? – PaulMcKenzie Feb 26 '21 at 07:23
  • Either write to a text file using `<<`, go back to using trivial types (such as char arrays) that do not contain pointers, or read up on [object serialization](/questions/523872/how-do-you-serialize-an-object-in-c). You probably got the "binary file code" from a poor C++ website or some `C` language-centric material. When you choose to do things this way, you are limited to trivially-copyable types. You can't simply write out a blob of raw bytes, thinking you're saving the object. – PaulMcKenzie Feb 26 '21 at 07:28
  • I see your point, thanks a lot @PaulMcKenzie! – KIN Game Feb 26 '21 at 07:31

0 Answers0