Advertisement

loading a player from file

Started by July 26, 2000 10:36 PM
7 comments, last by Joker2000 24 years, 4 months ago
Ok, I''m having a few problems getting this loading routine to work right. The code is listed below along with the errors I get. It might look long, but it''s really not that bad.

class CPlayer
{
public:
    CPlayer(string, bool, ushort, ushort, ushort, ulong, ulong, ushort);
    ~CPlayer() { }
    static CPlayer & CopyFromFileRec(const PlayerFileRec &r);
    static bool LoadSavedPlayer();
private:
    string playerName;        // ERROR 1
    bool hasWeapon;
    unsigned short health;
    unsigned short armor;
    unsigned short pocketMoney;
    unsigned bankMoney;
    unsigned experience;
    unsigned short skillLevel;
};

CPlayer & CPlayer::CopyFromFileRec(const PlayerFileRec &r)
{
    playerName = r.pName;
    hasWeapon = r.hWeapon;
    health = r.health;
    armor = r.armor;
    pocketMoney = r.pMoney;
    bankMoney = r.bMoney;
    experience = r.exp;
    skillLevel = r.skill;

    return *this;                // ERROR 2
}

bool CPlayer::LoadSavedPlayer()
{
    string loadName;
    cout << endl << "Enter the name of the player you would like to load.";
    getline(cin, loadName);
    PlayerFileRec rec;
    ifstream in("Players.dat", ios::in | ios::binary);
    bool status = rec.LoadFromFileRec(in, loadName);
    if(status)
        CPlayer::CopyFromFileRec(rec);
    else
        cerr << "Player " << loadName << " Not Found" << endl;
    in.close();
    return status;
}

struct PlayerFileRec
{
string pName;
bool hWeapon;
unsigned short health, armor, pMoney, bMoney, exp, skill;
bool LoadFromFileRec(istream ∈, const string &loadName);
};

bool PlayerFileRec::LoadFromFileRec(istream ∈, const string &loadName)
{
    do
    {
        in.read((char *)this,sizeof(PlayerFileRec));
        if(loadName == pName)
            return true;
    } while(in.good());
    return false;
}
 
The errors I''m getting are: 1.) "Can''t use playerName, hasWeapon, etc. without an object" 2.) Can''t use "return *this" because it''s not inside a member function. Ok, I fixed 1 by making the members static, but that looked weird having everything static. Do I have to or is there another way? And I don''t know what the heck is up with #2...this IS inside a member function. What''s going on, please help. --- Joker2000 Stevie Ray Vaughan - The Legend
A static method does not contain the keyword ''this''. Since this is a valid pointer to the instance of the class, declaring something static does not gaurantee that the class has been instantiated. That is why you can not return this.

If you want to return a player object from CopyFromFile, then you will need to instantiate an object of type player inside the method and return that.

Since you are returning it as a reference and not as an object, you will be required to create an instance using new.

It appears that you simply want to initialize an instance of CPlayer from an input file.

If so, why do you want to return a CPlayer object? Simply populate your CPlayer attributes as you read in the data from the file.

remove the static as well. There should be no reason why this method should be static. Not in it''s current implementation.

Alek
Advertisement
First off:

Don''t use static unless you understand why you are making it static to begin with, otherwise you would know that static class members don''t have a THIS pointer. It kind of defeats the purpose...

Second:

I can''t really help you with the first one because you are either trying to use an object that you haven''t really declared or something to that effect based on your "error message".

YAP-YFIO,
deadlinegrunt

~deadlinegrunt

Guess Alex beat me to it.

(Moved to a new place and high speed doesn''t come with more for another two weeks. Sorry a$$ dial up crap... )

YAP-YFIO,
deadlinegrunt

~deadlinegrunt

But if you look at the function bool CPlayer::LoadSavedPlayer(), it needs to be called without an object, right? Because all it''s going to do is search a file...it doesn''t need an object does it? You see, this is where I''m getting totally confused. When do I need a class object and when don''t I? What''s the difference between:

CPlayer * pTempPlayer;
and
CPlayer * pTempPlayer = new CPlayer();

I know this sounds really lame, but I wish somebody would just write me a simple example of how to get all this to work. This is pretty much the way I had everything planned out in my mind:

1.) SavePlayer() fills struct PlayerFileRec with the data from class CPlayer and saves the struct to disk.
2.) LoadPlayer() scans the copies of struct PlayerFileRec on disk, looks for a match, and, if found, loads struct PlayerFileRec with the appropriate data. Then it copies that data to class CPlayer. Are you guys saying to bypass loading the data to the struct and go directly to the class?

Everytime I run this routine, even after modifications, I get tons of access violation errors (I''m guessing from null pointers but I''m not sure). My reasoning for filling in struct PlayerFileRec and saving that was because someone said if I just saved class CPlayer I would be saving the memory locations to the file and not the data. I think my save player routine works, someone just needs to show me how to load a player.


---
Joker2000
Stevie Ray Vaughan - The Legend
I made this little demo after reading This File I/O Doc:

    #include <fstream.h>class human {	public:		human();		void setName(char*);		char* getName();	private:		char* name;};human::human() {	name = "";};void human::setName(char* n) {	name = n;};char* human::getName() {	return name;};void main() {	human h;	h.setName("brian");	ofstream fout("file.dat", ios::binary);	fout.write((char *)(&h), sizeof(human));	fout << flush;	fout.close();	human d;		ifstream fin("file.dat", ios::binary);	fin.read((char *)(&d), sizeof(human));	fin.close();	cout << d.getName();};    


It creates a human object then saves it to a binary file... then it loads it back up.

40

www.databyss.com
www.omlettesoft.com

"Don''t meddle in the affairs of wizards, for they are subtle and quick to anger."
-40
Advertisement
Wow dude, you were fed a whole lot of misinformation
First off, don''t use static functions unless you have a really good reason for doing so. In this case you don''t.

There''s no reason for loading through a struct instead of loading directly into the class. Whoever told you it would save memory locations was either wrong or you misunderstood. However, if you want to save through a struct there''s no reason you can''t do that either. Here''s how (in psuedo-code):

    SavePlayerFunc ( ){   PlayerRecStruct prs;   // file prs with data   prs.Name = playerName;   // ...      // write data to the file   ostream.WriteData ( prs );}LoadPlayerFunc ( ){   PlayerRectStruct prs;   // read data from file   istream.ReadData ( prs );   // fill members   playerName = prs.Name;}    


There are cases where you will want to use an intermidiate struct to load data from a file, generally when using other people''s file formats.

To answer your second question..

MyClass* pObject;

That declares a variable, pObject, which is a pointer variable. But right now it points to a random region of memory. We want it to point to an object of type MyClass. Thus:

pObject = new MyClass;

The new operator allocates memory for an object, creates the object at that memory location, then returns the memory address used by pointers to access the object.

Since you don''t seem familiar with how pointers work I''d recommend you drop everything and go read a C++ tutorial before doing anything else. It''s invalid pointers which are causing all the crashes in your program. Also, you don''t seem to understand classes.. you''re trying to use them as namespaces - simply groupings of variables under one name. Again, go read up on C++ and it''s fairly easy to see what you''re doing wrong. Good luck!

-RWarden (roberte@maui.net)
Occasionally I''ve seen code like:

ofstream datafile(filename);
datafile.write((char *)&blah, sizeof(blah));

and now I''m seeing:

ostream.WriteData(blah);
istream.ReadData(blah);

What is the difference, or is there any? Is one a new feature introduced by C++?

OR

Am I just incredibly stupid (yes) and is the latter code snippit simply psuedo-code. (If it is, I will feel very bad...and dumb!)


---
Joker2000
Stevie Ray Vaughan - The Legend
No, you''re right about the syntax of ostream/istream. It''s just psuedo-code .

-RWarden (roberte@maui.net)

This topic is closed to new replies.

Advertisement