problem reading from a binary file

I am trying to write students to a binary file then read from the file and fill the mystudentVector. I am not sure where to begin. I am getting it to write to a file, it's the read that I'm having problems with.

This is just part of my code :

#ifndef STUDENT_HPP_
#define STUDENT_HPP_
#include <string>
#include <cstring>
#include <iostream>
#include <fstream>
#include "utilities.hpp"

fstream yourFile;
fstream aFile;
const int MAXROWS = 100;


//***********STUDENT ENUMS*************//


enum college {
LPC,
SFO,
BRK,
SLU,
WASHU,
CSC,
};//enum college


enum degreeMajor {
CS,
CIS,
MTH,
MUS,
BUIS,
VIT,
PHY,
ASTR,
ENG,
};//enum degreeMajor


//*********STUDENT STRUCTURES**********//


struct student {
int stuID; //4 characters long
string fname; //23 characters long
string lname; //29 characters long
college attendingCollege;
degreeMajor major;
double gpa; //0.0-4.0
double age; //14-90
double grades[MAXROWS]; //Each 0-100
int totalGrades;
};//struct student


struct Cstudent {
int stuID;
char fname[24];
char lname[30];
college attendingCollege;
degreeMajor major;
double gpa;
double age;
double grades[MAXROWS];
int totalGrades;
};//struct Cstudent


//*****STUDENT FUNCTION PROTOTYPES*****//

college inputCollege(void);
degreeMajor inputMajor(void);
string collegeToString(college);
string majorToString (degreeMajor);
void readStudents(vector<student> &, student, Cstudent, fstream &);
void writeStudents(vector<student> &, student, Cstudent, fstream &);

//**********STUDENT FUNCTIONS**********//


degreeMajor inputMajor(void){
int anInt;

cout << "0. CS\n";
cout << "1. CIS\n";
cout << "2. MTH\n";
cout << "3. MUS\n";
cout << "4. BUIS\n";
cout << "5. VIT\n";
cout << "6. PHY\n";
cout << "7. ASTR\n";
cout << "8. ENG\n";
anInt = enterInt("Please enter what major the student is pursuing: ", 0, 8);
return static_cast<degreeMajor>(anInt);
}//inputMajor


college inputCollege(void){
int anInt;

cout << "0. LPC\n";
cout << "1. SFO\n";
cout << "2. BRK\n";
cout << "3. SLU\n";
cout << "4. WASHU\n";
cout << "5. CSC\n";
anInt = enterInt("Please enter what school the student is attending: ", 0, 5);
return static_cast<college>(anInt);
}//inputCollege


string collegeToString (college aCollege) {
string returnString;
if (aCollege == LPC)
returnString = "LPC";
if (aCollege == SFO)
returnString = "SFO";
if (aCollege == BRK)
returnString = "BRK";
if (aCollege == SLU)
returnString = "SLU";
if (aCollege == WASHU)
returnString = "WASHU";
if (aCollege == CSC)
returnString = "CSC";

return returnString;
}//collegeToString


string majorToString (degreeMajor aMajor) {
string returnString;
if (aMajor == CS)
returnString = "CS";
if (aMajor == CIS)
returnString = "CIS";
if (aMajor == MTH)
returnString = "MTH";
if (aMajor == MUS)
returnString = "MUS";
if (aMajor == BUIS)
returnString = "BUIS";
if (aMajor == VIT)
returnString = "VIT";
if (aMajor == PHY)
returnString = "PHY";
if (aMajor == ASTR)
returnString = "ASTR";
if (aMajor == ENG)
returnString = "ENG";

return returnString;
}//majorToString


void writeStudents(vector<student> &mystudentVector, student myStudent, Cstudent myCStudent, fstream &yourFile) {
char userInput;

yourFile.open("students.bin", ios::in | ios:: binary);
if (yourFile.fail()) {
yourFile.close();
}//if
else {
cout << "File already exists. Would you like to overwrite it?" << endl;
cout << "<Y>es, <N>o ==> ";
while (true) {
cin >> userInput;
if (userInput == 'Y' || userInput == 'y') {
yourFile.close();
yourFile.open("students.bin", ios::out | ios:: binary);
for (unsigned int i = 0; i < mystudentVector.size(); i++) {
strcpy(myCStudent.fname, mystudentVector[i].fname.c_str());
strcpy(myCStudent.lname, mystudentVector[i].lname.c_str());
yourFile.write(reinterpret_cast<char *> (&myCStudent), sizeof(myCStudent));
}//for
yourFile.close();
break;
}//if
else if (userInput == 'N' || userInput == 'n') {
cout << "Not writing the file." << endl;
yourFile.close();
break;
}//else if
else {
cout << "Invalid selection, please try again." << endl;
}//else
}//while
}//else
}//writeBoats


void readStudents(vector<student> &mystudentVector, student myStudent, Cstudent myCStudent, fstream &yourFile) {

string aString;
char aCString[54];

yourFile.open("students.bin", ios::in | ios::binary);
if (yourFile.fail()) {
cout << "File does not exist, try again later.\n";
yourFile.close();
}//if
else {
yourFile.open("students.bin", ios::out | ios::binary);
cout << "Open successful, reading students from students.bin" << endl;
for (unsigned int i = 0; i < mystudentVector.size(); i++) {
yourFile.read(reinterpret_cast<char *>(&myCStudent), sizeof(&myCStudent));
cout << "done copying" << endl;
if(yourFile.eof()) {
aString = aCString;
mystudentVector.push_back(myStudent);
break;
}//if
}//for
yourFile.close();
}//else
}//readStudents


#endif /* STUDENT_HPP_ */
Last edited on
This is just part of my code

I suspect there are a number of errors, one of the obvious ones is in function readStudents() at this line:
 
yourFile.read(reinterpret_cast<char *>(&myCStudent), sizeof(&myCStudent));
The wrong length is specified. It should be sizeof(myCStudent) without the &

In trying to read your code, I couldn't understand why there were additional parameters student myStudent and Cstudent myCStudent passed. If they are needed at all, they should only be local variables declared inside the function.

Also in my opinion there seemed little point in passing the fstream &yourFile as a parameter either, since the function opens and closes files in any case.

I ended up re-writing some of this code. For simplicity I omitted much of the preliminary checking of whether the file exists etc.

I passed just the vector and a string containing the filename as parameters.

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
void writeStudents(const std::vector<student> &mystudentVector, std::string fname) 
{
    std::ofstream yourFile(fname, std::ios::binary);
    if (yourFile.fail()) 
    {
        return;
    } 
    
    Cstudent cstud;

    for (unsigned int i = 0; i < mystudentVector.size(); i++)
    {
        cstud.age              = mystudentVector[i].age;
        cstud.attendingCollege = mystudentVector[i].attendingCollege;
        cstud.gpa              = mystudentVector[i].gpa;
        cstud.major            = mystudentVector[i].major;
        cstud.stuID            = mystudentVector[i].stuID;
        cstud.totalGrades      = mystudentVector[i].totalGrades;
        for (int row=0; row<MAXROWS; row++)
            cstud.grades[row]    = mystudentVector[i].grades[row];      
        strcpy(cstud.fname, mystudentVector[i].fname.c_str());
        strcpy(cstud.lname, mystudentVector[i].lname.c_str());
        
        yourFile.write(reinterpret_cast<char *> (&cstud), sizeof(cstud));
    } 
}


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
int readStudents(std::vector<student> &mystudentVector, std::string fname) 
{
    std::ifstream yourFile(fname, std::ios::binary);
    
    if (!yourFile)
    {
        std::cout << "Error opening input file: " << fname << '\n';
        return false;
    }

    Cstudent cstud;
    student  stud;
        
    mystudentVector.clear();        
    while (yourFile.read(reinterpret_cast<char *>(&cstud), sizeof(cstud)))
    {
        stud.age              = cstud.age;
        stud.attendingCollege = cstud.attendingCollege;
        stud.gpa              = cstud.gpa;
        stud.major            = cstud.major;
        stud.stuID            = cstud.stuID;
        stud.totalGrades      = cstud.totalGrades;
        stud.fname            = cstud.fname;
        stud.lname            = cstud.lname;        
        for (int row=0; row<MAXROWS; row++)
            stud.grades[row]    = cstud.grades[row];
                    
        mystudentVector.push_back(stud);            
    }
	
    return (mystudentVector.size());
} 


Also, please use code tags, you are more likely to get a response.
http://www.cplusplus.com/articles/jEywvCM9/


Hope this helps.

Topic archived. No new replies allowed.