So I'm having a bit of an issue of not being able to properly read a binary file into my structure. The structure is this:
struct Student
{
char name[25];
int quiz1;
int quiz2;
int quiz3;
};
It is 37 bytes (25 bytes from char array, and 4 bytes per integer). My .dat file is 185 bytes. It's 5 students with 3 integer grades. So each student takes up 37 bytes (37*5=185).
It looks something like this in plain text format:
Bart Simpson 75 65 70
Ralph Wiggum 35 60 44
Lisa Simpson 100 98 91
Martin Prince 99 98 99
Milhouse Van Houten 80 87 79
I'm able to read each of the records individually by using this code:
Student stud;
fstream file;
file.open("quizzes.dat", ios::in | ios::out | ios::binary);
if (file.fail())
{
cout << "ERROR: Cannot open the file..." << endl;
exit(0);
}
file.read(stud.name, sizeof(stud.name));
file.read(reinterpret_cast<char *>(&stud.quiz1), sizeof(stud.quiz1));
file.read(reinterpret_cast<char *>(&stud.quiz2), sizeof(stud.quiz2));
file.read(reinterpret_cast<char *>(&stud.quiz3), sizeof(stud.quiz3));
while(!file.eof())
{
cout << left
<< setw(25) << stud.name
<< setw(5) << stud.quiz1
<< setw(5) << stud.quiz2
<< setw(5) << stud.quiz3
<< endl;
// Reading the next record
file.read(stud.name, sizeof(stud.name));
file.read(reinterpret_cast<char *>(&stud.quiz1), sizeof(stud.quiz1));
file.read(reinterpret_cast<char *>(&stud.quiz2), sizeof(stud.quiz2));
file.read(reinterpret_cast<char *>(&stud.quiz3), sizeof(stud.quiz3));
}
And I get a nice looking output, but I want to be able to read in one whole structure at a time, not just individual members of each structure at a time. This code is what I believe needed to accomplish the task, but... it doesn't work (I'll show output after it):
*not including the similar parts as far as opening of the file and structure declaration, etc.
file.read(reinterpret_cast<char *>(&stud), sizeof(stud));
while(!file.eof())
{
cout << left
<< setw(25) << stud.name
<< setw(5) << stud.quiz1
<< setw(5) << stud.quiz2
<< setw(5) << stud.quiz3
<< endl;
file.read(reinterpret_cast<char *>(&stud), sizeof(stud));
}
OUTPUT:
Bart Simpson 16640179201818317312
ph Wiggum 288358417665884161394631027
impson 129184563217692391371917853806
ince 175193530917020655191851872800
The only part it doesn't mess up is the first name, after that it's down the hill.. I've tried everything and I've no idea what is wrong. I've even searched through the books I have and I couldn't find anything. Things in there look like what I have and they work, but for some odd reason mine doesn't. I did the file.get(ch) (ch being a char) at byte 25 and it returned K, which is ASCII for 75.. which is the 1st test score, so, everything's where it should be. It's just not reading in my structures properly.
Any help would be greatly appreciated, I'm just stuck with this one.
EDIT: After receiving such a large amount of unexpected and awesome input from you guys, I've decided to take your advice and stick with reading in one member at a time. I made things cleaner and smaller by using functions. Thank you once again for providing such quick and enlightening input. It's much appreciated.
IF you're interested in a workaround that's not recommended by most, scroll towards the bottom, to the 3rd answer by user1654209. That workaround works flawlessly, but read all the comments to see why it's not favored.
sizeof(Student)you will see that it's not 37 bytes. It might possibly be 40 or 56.