Objects and File I/O

Hi,
Whats wrong the the piece of code below?

When I read the file back in after writing, some (but not all) of the data is corrupt. Any ideas?

struct Data
{
  int Num_1;
  char Char[11];
  int Num_2,
      Num_3;
  //...
};

class Container_data
{
   struct Data *Ptr_data;
  //...

 public
  //..
  void Write_to_disk();    
  void Read_from_disk();

};

void Container_data::Write_to_disk()
{
  ofstream outdata(FileName);
  if (!outdata)
  {
       cout <<"Cannot open file for writing\n";
  }

 for (int za = 0; za <= no_of_results; za++)
 {
   outdata.write((unsigned char *) &Ptr_data[za], sizeof(Ptr_data[za]));
 }
 outdata.close();
}

void Container_data::Read_from_disk()  
{
  ifstream indata(FileName);
  if (!indata)
  {
    cout <<"Cannot open file for reading\n";
  }
  int zz = 0;
  while (!indata.eof())
  {
    indata.read((unsigned char *) &Ptr_data[zz], sizeof(Ptr_data[zz]));
    zz++;
  }
  no_of_results = zz;
  indata.close();
}
philipwAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
The problem is/are

 outdata.write((unsigned char *) (Ptr_data +zz), sizeof(Ptr_data[za]));

This should read

 outdata.write((unsigned char *) &Ptr_data[za], sizeof(struct Data);

and

   indata.read((unsigned char *) &Ptr_data[zz], sizeof(Ptr_data[zz]));

which should read

   indata.read((unsigned char *) (Ptr_data +zz), sizeof(sizeof(struct Data));

Feel free to ask if you need more information!
0
jkrCommented:
Ooops, sorry, messed it up ;-)

The lines should be

indata.read((unsigned char *) (Ptr_data +zz), sizeof(struct Data));

and

outdata.write((unsigned char *) (Ptr_data +zz), sizeof(struct Data));
0
philipwAuthor Commented:
Sorry jkr, still have the same problem.  I assume the rest of the program is OK because I have no problems working with the data once I've entered it.
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

nietodCommented:
jkr seems to be right.  But the file needs to be in binary mode.

void Container_data::Write_to_disk()
{
   ofstream outdata(FileName,ios:binary);
   if (!outdata)
      cout <<"Cannot open file for writing\n";

    for (int za = 0; za <= no_of_results; za++)
         outdata.write((unsigned char*) Ptr_data[za],sizeof(Data));
    outdata.close();
}

void Container_data::Read_from_disk()  
{
   ifstream indata(FileName,ios::binary);
   if (!indata)
        cout <<"Cannot open file for reading\n";

   int zz = 0;
   while (!indata.eof())
   {
      indata.read((unsigned char *) Ptr_data[zz],sizeof(Data));
      zz++;
    }
    no_of_results = zz;
    indata.close();
}

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
nietodCommented:
Also, you never initialize the Ptr_data[] array (at least in the code we see, so that is a bigg problem.  You need to allocate space for this array AND for the Data structures that you are reading into.   Do you do so?
0
philipwAuthor Commented:
Sorry jkr, still have the same problem.  I assume the rest of the program is OK because I have no problems working with the data once I've entered it.
0
philipwAuthor Commented:
Thanks to both neitod and jkr for their answers. I'm only sorry I can only award points to neitod.

Could someone tell me though what (Ptr_data +zz) means in jkr's answer? I'm not sure what it means but it works.
0
nietodCommented:
Sorry, jkr, I didn't actually answer because I knew you would have found it when you came back, but philipw accepted the comment as an answer.

>>what (Ptr_data +zz) means

When you add and subtract from a pointer it results in a pointer that is "shifted" forward or backwards in memory by the number of items that you added or subtracted.  Thus if "SomePtr" points to an array of "int", then "SomePtr+0" results in a pointer to the first item, "somePtr+1" results in a pointer to the 2nd item. "SomePtr+2" points to the 3rd item and so on.

In C/C++ pointers and arrays are almost identical.  (This is not true in many other languages, except maybe assembly.)  The way to think about it is that the "name" of an array variable is a pointer to the 1st entry in the array.  But this name can be treaded like a pointer in almost all respects.  so in

int IntArray[10];
int *IntPtr = IntArray;

"IntArray" is a lot like IntPtr.  They both act like pointers to ints.  So

int i = *(IntArray + 1); // Get 2nd entry from the array.
int i = IntArray[1];       // Get 2nd entry from the array.
int i = *(IntPtr + 1);    // Get 2nd entry from the array.
int i = IntPtr[1];          // Get 2nd entry from the array.

0
jkrCommented:
>>Sorry, jkr, I didn't actually answer
>>because I knew you would have found
>>it when you came back

No problem, that's the difficulty with timezones different from continent to continent ;-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.