read from and write to binary files: array of structures

Hey,
I've made an array of structures. I did so by making an pointer to an array of pointers (by dynamic allocation),and allocate the address of a structure to one of these last pointers. Everything should be written to a binary file.
Here's the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <fstream>
using namespace std;
struct STUDENT
{
       int ID;
       char name[256];
       char firstName[256];     
};

int main()
{
    char cID[256];
    int count=0;char cCount[256];
    cout << "How many records:";
    cin.getline(cCount,256);
    count=atoi(cCount);
    STUDENT** x=new STUDENT*[count];
    for(int i=0;i<count;i++)
      {x[i]=new STUDENT;
      }
    for(int i=0;i<count;i++)
      {cID[0]=0;
       cout << "ID:";cin.getline(cID,256);x[i]->ID=atoi(cID);
       cout << "Naam:";cin.getline(x[i]->name,256);
       cout << "Voornaam:";cin.getline(x[i]->firstName,256);
      }
    char fileName[256];
    cout << "Name file:";cin.getline(fileName,256);
    ofstream outfile(fileName,ios::out);
    if(!outfile){cout << "ERROR";exit(1);}
    for(int i=0;i<count;i++)
      {outfile.write((char*)&x[i],sizeof(x[i]));
      }    
    outfile.close();
    return 0;
}


The problem is when I try to read these records in this code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <fstream>

using namespace std;
struct STUDENT
{
       int ID;
       char name[256];
       char firstName[256];         
};
int main()
{
    STUDENT x;
    char fileName[256];
    cout << "Naam bestand:";cin.getline(fileName,256);
    ifstream infile(fileName,ios::in|ios::binary);
    if(!infile){cout << "ERROR";exit(1);}
    int counter=0;
    while(!infile.eof())
      {infile.read((char*)&x,sizeof(STUDENT));
       cout << x.ID << endl;
       cout << x.name << endl;
       cout << x.firstName << endl;
       cout << "-------------------------" << endl;
       counter++;
      }    
    infile.close();
    cout << counter << " records available!" << endl;
    return 0;
}


It always reads strange characters!
What's wrong with this code?

Thanks
Last edited on
I think part of the problem is

1
2
3
    for(int i=0;i<count;i++)
      {outfile.write((char*)&x[i],sizeof(x[i]));
      } 


x is an array of pointers, so one dereference gives a pointer, not the actual STUDENT object, so it should be:
1
2
    for(int i=0;i<count;i++)
      outfile.write((char*)&*(x[i]),sizeof(STUDENT));


likewise, the size needs to be the size of a student, not a student pointer.

now the reader will keep taking tying to read till end of file is reached, but the end of file flag doesn't come up when the last element is reached but when you try to access one more, so it should be:

1
2
3
4
5
6
7
8
9
10
	while (true) {
       infile.read((char*)&x,sizeof(STUDENT));
	   if (infile.eof())
		   break;
       cout << x.ID << endl;
       cout << x.name << endl;
       cout << x.firstName << endl;
       cout << "-------------------------" << endl;
       counter++;
      }  


otherwise you'll end up with a repeat of your last element
Last edited on
Hey thanks! It turned out well! I changed the reading-code:

1
2
3
4
5
6
7
8
9
10
infile.read((char*)&x,sizeof(STUDENT));
    while(!infile.eof())
      {
       cout << x.ID << endl;
       cout << x.name << endl;
       cout << x.firstName << endl;
       cout << "-------------------------" << endl;
       counter++;
       infile.read((char*)&x,sizeof(STUDENT));
      } 


There was only one problem when I tried to add some records to the existing file: the last added records could not be read properly (hence it understood how many records there were!). So I changed something in
the writing code, something that seemed rather strange: you dereference and then ask for the address (which seems unnecessary to me, I think).

So I changed
 
outfile.write((char*)&*(x[i]),sizeof(STUDENT));

into
 
outfile.write((char*)(x[i]),sizeof(STUDENT));

Now it reads the last added records properly! Although I do not understand why it should not read properly when you use &*(x[i]):
Topic archived. No new replies allowed.