0

In my computer science class, we are using fstream to read and write into files. This something we have done before, but we are required to use the fstream's read and write functions. When I use the write function in SaveToBinary and the read function in LoadFromBinary it causes an error to occur at line 144 or line 53. The error shows up at line 1222 in xmemory. I have no idea what the error is, but I believe the write and read function are causing it because using >> and << to access the file works fine.

Here is my code. There is some testing code that is either commented out or outputting to the console.

#include <iostream>
#include <string>
#include <vector>
#include <fstream>

using namespace std;

struct Student {
    string mName = "Name"; //Switch to char*
    int mAge = 0;
    double mGrades[4] = { 0, 0, 0, 0 };
    double mAverage = 0;
};

//Prototypes
vector<Student> LoadFromText(string);
string SaveToBinary(vector<Student>&);
vector<Student> LoadFromBinary(string);

void display(Student student) {
    cout << "Name: " << student.mName << endl;
    cout << "Age: " << student.mAge << endl;

    cout << "Grades: ";
    for (int j = 0; j < 4; j++) {
        cout << student.mGrades[j] << " ";
    }
    cout << endl;

    cout << "Average: " << student.mAverage << endl;
    cout << endl;
}


int main() {
    vector<Student> students = LoadFromText("students.txt");
    string fileName = SaveToBinary(students);
    vector<Student> studentsFromBinary = LoadFromBinary(fileName);

    cout << "Main Method" << endl;

    for (int i = 0; i < studentsFromBinary.size(); i++) {
        display(studentsFromBinary[i]);
    }

    cout << "Printed" << endl;
    return 0; //ERROR FLAGS HERE
}

//THIS METHOD READS DATA FROM "student.txt" INTO A vector<student> AND RETURNS
vector<Student> LoadFromText(string aFileName) {
    fstream file;
    file.open(aFileName, ios::in);
    vector<Student> students;

    if (file.is_open()) {
        Student temp;

        string name, nameLast;
        const int amountOfGrades = 4;
        double total = 0;

        cout << "file opened" << endl;

        while (file >> name) {
        //Save Name
            //Convert string to char*
            file >> nameLast;
            name = name + " " + nameLast;
            
            temp.mName = name;

        //Save Age
            file >> temp.mAge;

        //Save Grades and average
            for (int i = 0; i < amountOfGrades; i++) {
                file >> temp.mGrades[i];
                total += temp.mGrades[i];
            }

            temp.mAverage = total / amountOfGrades;
            total = 0;

            //display(temp);

            students.push_back(temp);
        }
    }
    else
        cout << "\n\tError: " << aFileName << " not found" << endl;

    file.close();

    return students;
}

//THIS METHOD READS DATA FROM vector<student> INTO "student.dat" AND RETURNS "student.dat"
string SaveToBinary(vector<Student>& aStudents) {
    fstream file;
    file.open("students.dat", ios::out | ios::binary);

    if (file.is_open()) {
        for (int i = 0; i < aStudents.size(); i++){
            Student student = aStudents[i];
            file.write(reinterpret_cast<char*>(&aStudents[i]), sizeof(aStudents[i]));

            /*file << student.mName << endl;
            file << student.mAge << endl;
            for (int i = 0; i < 4; i++) {
                file << student.mGrades[i] << endl;
            }
            file << student.mAverage << endl;*/
        }
    }
    else
        cout << "\n\tError: " << "students.dat" << " not found" << endl;

    file.close();

    return "students.dat";
}

//THIS METHOD READS DATA FROM "student.DAT" INTO A vector<student> AND RETURNS
vector<Student> LoadFromBinary(string aFileName) {
    vector<Student> students;
    fstream file;
    file.open(aFileName, ios::in | ios::binary);

    if (file.is_open()) {
        Student temp;

        while (!file.eof()) {
            file.read(reinterpret_cast<char*>(&temp), sizeof(temp));

        /*  string last;
            file >> temp.mName >> last;
            temp.mName += " " + last;
            file >> temp.mAge;
            for (int i = 0; i < 4; i++) {
                file >> temp.mGrades[i];
            }
            file >> temp.mAverage;*/

            students.push_back(temp);
            cout << students.size() << endl;

            //Output
                cout << temp.mName << endl;
                cout << temp.mAge << endl;
                for (int i = 0; i < 4; i++) {
                    cout << temp.mGrades[i] << endl;
                }
                cout << temp.mAverage << endl;

                cout << endl;
        }

        students.resize(students.size() - 1);
    } //ERROR FLAGS HERE
    else
        cout << "\n\tError: " << "students.dat" << " not found" << endl;
    
    file.close();

    return students;
}

Here is the text file we are using.

Augustina Aceto
23
62.25 100 40.50 100


Louann Levron
21
40.80 75.30 52.75 64.50


Jaimie Jumper
23
99.0 0.0 40.60 75.50


Lanie Labelle
22
94.0 100.0 90.30 100.0


Phillip Pless
24
100.0 0.2 40.1 75.7
  • `string mName = "Name"; //Switch to char*` only follow through on the comment if you'll lose marks on the assignment if you don't. The code grows whole orders of magnitude more complicated if you try to manage your own raw pointers to allocations. – user4581301 Nov 04 '21 at 19:56
  • `sizeof(aStudents[i])` -- For laughs, do this: `std::vector test(1000); std::cout << sizeof(test);` -- That creates a vector of 1000 students. What value do you expect to be displayed? If you think it will be something like 1000 or bigger, think again. The `sizeof()` doesn't do what you think it does, thus that entire line of code that attempts to write and read to a binary file could never work properly. Once you see that's a problem, everything else should be easier to understand once you read the duplicate link. – PaulMcKenzie Nov 04 '21 at 20:14

0 Answers0