Pergunta

I am C++ beginner, What I want to do is to read and write Staff objects that I have created in my program.

Below is my Write method:

void Staff::writeStaffFile(){
const int vectorSize = staffList.size();
ofstream staffDetailsFile("staffDetails.txt", ios::out | ios::binary);
if (!staffDetailsFile){
    cerr << "\nFile open error - Error writing staff details" << endl;
    return;
    }

for (int i=0; i<vectorSize; i++){
    staffDetailsFile.write(reinterpret_cast< const char* >(&staffList[i]), sizeof(Staff));
    }
staffDetailsFile.close();
}

Staff objects are saved in a vector, and here I am trying to save all those staff objects available in the vector into the file. It works and writes data into the file.

Where I have gone wrong is reading the file. This is my read method:

void Staff::readStaffFile(){
ifstream staffDetailsFile("staffDetails.txt", ios::in | ios::binary);
if (!staffDetailsFile)
    cerr << "\nFile open error - Staff details not found" << endl;
else {
    Staff *temp = (Staff *)malloc(sizeof(Staff));
    while(!staffDetailsFile.eof()){
        staffDetailsFile.read(reinterpret_cast<char *>(temp),sizeof(Staff));
        if (temp != NULL)
            Staff::insertAccount(temp);
        }
    }
}

When I run this part, I get the following error in Visual Studio.

Unhandled exception at 0x53950E9A (msvcr110d.dll) in StaffPersonnelSystem.exe: 0xC0000005: Access violation reading location 0x00F5BF28.

I can't seem to understand where I have gone wrong, I would be very greatful if somebody can help me with this code.

PS: This is my staff class definition:

#include <iostream>
#include <string>
#include <malloc>
#include <vector>
#include "Person.h"

#ifndef STAFF_H
#define STAFF_H

class Staff : public Person {

public:
    Staff(int const, string,string,int,string,string,char,Designation,Department,Date,string,string,Date,bool); //staff constructor

    //set methods
    void setStaffIDNumber(int const);
    void setUsername(string);
    void setPassword(string);
    void setAccessLevel(int);


    //edit, modify other staff accounts
    static void addStaff(int);
    static int generateStaffID();
    static void deleteStaff(int, Staff*);
    static void changePassword(Staff*);
    static bool modifyStaff(int, Staff*);
    static void insertAccount(Staff*);
    static void printStaffDetails(Staff*);
    static void writeStaffFile();
    static void readStaffFile();
    static bool isValidAccount(Staff*,string, string);
    static Staff* chooseStaffAccount();
    static void searchStaff();
    static void refreshVector();

    //get methods
    Staff getStaffAccount(string);
    int getAccessLevel();
    string getUserName();
    int getStaffID();
    string getPassword();

    //search staff accounts
    static Staff* searchStaffAccount(string); //search staff accounts by userName
    static Staff* searchByID(int); //search staff accounts by ID
    static void searchByDept(Department); //Get staff registered to perticular department
    static void searchByDesignation(Designation); //Get staff registered to perticular designation
    static void sortVector();
    static bool sortByID(Staff &lhs, Staff &rhs);
    static bool isVectorEmpty();

private:
    int staffIDNumber;
    string userName;
    string passWord;
    int accessLevel;

    };

#endif
Foi útil?

Solução

Your making several mistakes. The first is to think that you can do anything with a bitwise image written to a file. All data outside your program must be formatted in some way. If you want a binary format, you'll need functions to format and parse an int and a string. (Unless there's some strong reason for doing otherwise, you should probably use an existing format: XDR is probably the simplest.)

If your data were all basic data types (int, char[], etc.), writing and reading the bitwise image would probably seem to work. Until you changed compiler options, or version, or tried to use another system. Even basic types need formatting. (And of course, anything with pointers needs formatting; std::string almost certainly has pointers in its implementation.)

And finally: you use the results of staffDetailsFile.read without testing whether the read succeeded or not. That's undefined behavior. Your loop should probably be while ( staffDetailsFile.read( ... ) ). (But that will only get you the unformatted buffer; you'll still need to extract the data. And it's likely that you don't even know how many bytes to read, since your format for std::string is likely to have a variable length.)

Outras dicas

You cannot write to a file an object of Staff type, read it back and expect that it will work. Such thing is possible only if your class if POD (plain old data). Your Staff class is not a POD - it contains string objects. BTW your test if (temp != NULL) is wrong - if temp was not NULL before read call, it won't be NULL after it.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top