Thread: Question about classes and structures.

  1. #16
    Registered User
    Join Date
    Aug 2005
    Posts
    91
    Geez, Dae, you take meanings from my posts I never even knew were there...

  2. #17
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Quote Originally Posted by linkofazeroth
    No, you understood it right. I don't know how to make the program search in a file for a certain value and pull it up (I have a function called load()), so I'm stuck with separate files. Like, if I have a file that looks like this...

    Code:
    1
    5
    5
    4
    6
    0
    0
    1
    ...I can't (or don't know how to) make the program search for a specific number. Maybe if I could tell a function to look at a certain line in the file and pull that line's value out, that'd be helpful, but I don't know how.

    Did my previous post help you with your problem at all, though?
    I've been doing it like this:

    Code:
    #include <iostream>
    #include <fstream>
    
    class Human
    {
    private:
      int m_minHealth;
      int m_maxHealth;
      int m_minMana;
      int m_maxMana;
      int m_minStamina;
      int m_maxStamina;
            
    public:
      Human ();
    
      int GetMinHealth () { return m_minHealth; }
      void SetMinHealth (int p_minHealth) { m_minHealth = p_minHealth; }
    
      bool Save (const char*);
      bool Read (const char*);
    };
    
    Human::Human() : m_minHealth(100), m_maxHealth(100), m_minMana(50), m_maxMana(50), m_minStamina(75), m_maxStamina(75) { }
    
    bool Human::Save (const char* p_filename)
    {
      int index;
    
      FILE* saveFile = fopen (p_filename, "wb");
      if (saveFile == 0)
        return false;
      
      fseek (saveFile, 0, SEEK_SET);
      fwrite (&(m_minHealth), sizeof (m_minHealth), 1, saveFile);
      
      fseek (saveFile, sizeof (m_minHealth), SEEK_SET);
      fwrite (&(m_minHealth), sizeof (m_maxHealth), 1, saveFile);
      
      fseek (saveFile, ((sizeof (m_minHealth)) + (sizeof (m_maxHealth))), SEEK_SET);
      fwrite (&(m_minMana), sizeof (m_minMana), 1, saveFile);
      
      fseek (saveFile, ((sizeof (m_minHealth)) + (sizeof (m_maxHealth)) + (sizeof (m_minMana))), SEEK_SET);
      fwrite (&(m_maxMana), sizeof (m_maxMana), 1, saveFile);
      
      fseek (saveFile, ((sizeof (m_minHealth)) + (sizeof (m_maxHealth)) + (sizeof (m_minMana)) + (sizeof (m_maxMana))), SEEK_SET);
      fwrite (&(m_minStamina), sizeof (m_minStamina), 1, saveFile);
      
      fseek (saveFile, ((sizeof (m_minHealth)) + (sizeof (m_maxHealth)) + (sizeof (m_minMana)) + (sizeof (m_maxMana)) + (sizeof (m_minStamina))), SEEK_SET);
      fwrite (&(m_maxStamina), sizeof (m_maxStamina), 1, saveFile);
    
      fclose (saveFile);
      //if (written != m_size)
      //  return false;
    
      return true;
    }
    
    bool Human::Read (const char* p_filename)
    {
      int read = 0;
    
      FILE* infile = fopen (p_filename, "rb");
      if (infile == 0)
        return false;
    
      read = fread (this, sizeof(int), 6, infile);
    
      fclose (infile);
      //if (read != m_size)
      //  return false;
    
      return true;
    }
    
    int main ()
    {
      Human Hum1;
      
      std::cout << Hum1.GetMinHealth() << std::endl;
      Hum1.SetMinHealth(200);
      Hum1.Save ("player1.dat"); //save as 200
      std::cout << Hum1.GetMinHealth() << std::endl;
      Hum1.SetMinHealth(300); //set to 300
      Hum1.Read ("player1.dat"); //changes it back to 200
      std::cout << Hum1.GetMinHealth() << std::endl; //output 200
        
     
      std::cin.get();
    }
    The Save and Read methods use ol' C. The Save method shows how to seek to a certain spot (by how many bytes into the file you want to read, and how many bytes you want to read, ie. bytes 12-16 (m_minMana), or 0-4 (m_minHealth)), and the Read method reads the entire saved class into the class you're in (this).

    I'm not sure how to do it the C++ way, or how to seek to a specific variable without searching google and doing some reading. I might actually go do that now, itd be beneficial to know, and cplusplus.com has info on the specific functions.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  3. #18
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Dae, do you need <cstdio>?

    Oh, never mind . . . .
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #19
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by Dae
    I'm not sure how to do it the C++ way, or how to seek to a specific variable without searching google and doing some reading. I might actually go do that now, itd be beneficial to know, and cplusplus.com has info on the specific functions.
    Use ifstream/ofstream objects. The read/write methods for those objects are equivalent to the fread/fwrite functions. The seekp/seekg functions can perform the same task as the fseek function.

    I myself might go the path of overwriting the stream insertion/extraction operators for the class (<</>>) and end up with something like:

    Code:
    // Create our Human object Hum1
    Human Hum1;
    
    // Read from input file into Hum1 Human
    ifstream input("Player.Txt",ios::in|ios::binary);
    input >> Hum1;
    input.close();
    
    // Do stuff with the Hum1 Human
    
    // Write out data for Hum1 to the output file
    ofstream output("Player.Txt",ios::out|ios::binary);
    output << Hum1;
    output.close();
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  5. #20
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Quote Originally Posted by hk_mp5kpdw
    Use ifstream/ofstream objects. The read/write methods for those objects are equivalent to the fread/fwrite functions. The seekp/seekg functions can perform the same task as the fseek function.

    I myself might go the path of overwriting the stream insertion/extraction operators for the class (<</>>) and end up with something like:

    Code:
    // Create our Human object Hum1
    Human Hum1;
    
    // Read from input file into Hum1 Human
    ifstream input("Player.Txt",ios::in|ios::binary);
    input >> Hum1;
    input.close();
    
    // Do stuff with the Hum1 Human
    
    // Write out data for Hum1 to the output file
    ofstream output("Player.Txt",ios::out|ios::binary);
    output << Hum1;
    output.close();
    For the past couple hours I was checking that exact method out, heres the C++ equivalent of what I posted above for the text-adventure saving data style (I used if/else's to make it more versatile, save only health, read only health, read all, etc.):

    Code:
    bool Human::Save (bool p_minHealth, bool p_maxHealth, bool p_minMana, bool p_maxMana, bool p_minStamina, bool p_maxStamina)
    {
      long pos = 0;
    
      ofstream saveFile ("player2.dat", ofstream::binary);
      if (!saveFile) {
        cerr << "Error: file could not be opened" << endl;
        exit(1);
        return false;
      }
    
      if (p_minHealth)
        saveFile << m_minHealth << "\n";
      else
        saveFile.seekp (pos + sizeof (m_minHealth));
    
      pos = saveFile.tellp();
      if (p_maxHealth)
        saveFile << m_maxHealth << "\n";
      else
        saveFile.seekp (pos + sizeof (m_maxHealth));
        
      pos = saveFile.tellp();
      if (p_minMana)
        saveFile << m_minMana << "\n";
      else
        saveFile.seekp (pos + sizeof (m_minMana));
    
      pos = saveFile.tellp();
      if (p_maxMana)
        saveFile << m_maxMana << "\n";
      else
        saveFile.seekp (pos + sizeof (m_maxMana));
        
      pos = saveFile.tellp();
      if (p_minStamina)
        saveFile << m_minStamina << "\n";
      else
        saveFile.seekp (pos + sizeof (m_minStamina));
        
      pos = saveFile.tellp();
      if (p_maxStamina)
        saveFile << m_maxStamina << "\n";
      else
        saveFile.seekp (pos + sizeof (m_maxStamina));
    
      saveFile.close();
    
      return 1;
    }
    
    bool Human::Read (bool p_minHealth, bool p_maxHealth, bool p_minMana, bool p_maxMana, bool p_minStamina, bool p_maxStamina)
    {
      long pos = 0;
    
      ifstream readFile ("player2.dat", ofstream::binary);
      if (!readFile) {
        cerr << "Error: file could not be opened" << endl;
        exit(1);
        return false;
      }
    
      if (p_minHealth)
        readFile >> m_minHealth;
      else
        readFile.seekg (pos + sizeof (m_minHealth));
    
      pos = readFile.tellg();
      if (p_maxHealth)
        readFile >> m_maxHealth;
      else
        readFile.seekg (pos + sizeof (m_maxHealth));
        
      pos = readFile.tellg();
      if (p_minMana)
        readFile >> m_minMana;
      else
        readFile.seekg (pos + sizeof (m_minMana));
    
      pos = readFile.tellg();
      if (p_maxMana)
        readFile >> m_maxMana;
      else
        readFile.seekg (pos + sizeof (m_maxMana));
        
      pos = readFile.tellg();
      if (p_minStamina)
        readFile >> m_minStamina;
      else
        readFile.seekg (pos + sizeof (m_minStamina));
        
      pos = readFile.tellg();
      if (p_maxStamina)
        readFile >> m_maxStamina;
      else
        readFile.seekg (pos + sizeof (m_maxStamina));
    
      readFile.close();
    
      return 1;
    }
    
    int main ()
    {
      Human Hum1;
    
      std::cout << Hum1.GetMinHealth() << std::endl;
      Hum1.SetMinHealth(200);
      Hum1.Save (1, 0, 0, 0, 0, 0);
      std::cout << Hum1.GetMinHealth() << std::endl;
      Hum1.SetMinHealth(300);
      Hum1.Read (1, 0, 0, 0, 0, 0);
      std::cout << Hum1.GetMinHealth() << std::endl;
      
      std::cin.get();
    }
    I just wonder if all that seeking will make it slower, let alone all that reading/writing (since I think >> and << are formatted also).

    I also liked using the C version cause the .dat file was like.. encrypted (maybe it was storing the exe of the struct, and thats what was being imported?), where as in this version its just the value.
    Last edited by Dae; 08-30-2005 at 03:56 PM.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 06-17-2005, 07:31 AM
  2. Pointers to Classes || pointers to structures
    By C++Child in forum C++ Programming
    Replies: 24
    Last Post: 07-30-2004, 06:14 PM
  3. Classes and Structures.
    By jrahhali in forum C++ Programming
    Replies: 6
    Last Post: 03-28-2004, 05:03 PM
  4. Structures, Unions and Classes
    By Makoy in forum C++ Programming
    Replies: 2
    Last Post: 02-23-2004, 02:57 PM
  5. structures fooloing to look like classes
    By samsam1 in forum C++ Programming
    Replies: 4
    Last Post: 01-18-2003, 11:43 AM