2014-01-20 3 views
0

Я начинаю с C++, Что я хочу сделать, так это читать и писать объекты Staff, которые я создал в своей программе.Чтение и запись объектов C++ в файлы с произвольным доступом

Ниже мой метод записи:

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(); 
} 

объекты Сотрудников сохраняются в векторе, и здесь я пытаюсь спасти все те сотрудник объектов доступны в векторе в файл. Он работает и записывает данные в файл.

Если я ошибался, читайте файл. Это мой метод чтения:

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); 
     } 
    } 
} 

Когда я запустил эту часть, я получаю следующую ошибку в Visual Studio.

Необработанное исключение в 0x53950E9A (msvcr110d.dll) в StaffPersonnelSystem.exe: 0xC0000005: Access местонахождения чтения нарушение 0x00F5BF28.

Я не могу понять, где я ошибся, я был бы очень благодарен, если кто-то может помочь мне с этим кодом.

PS: Это мое определение класса персонал:

#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 
+0

Покажите нам определение класса персонала. –

+0

Обычный способ сериализации и десериализации состоит в том, чтобы перегрузить операторы вставки/извлечения для вашего класса, чтобы принять и вернуть ostream &/istream &, а затем в этих методах вызывать операции ввода/извлечения отдельных элементов данных. Memcpy будет работать только тогда, когда все ваши члены данных являются примитивами, а не указателями или ссылками. В вашем случае у вас есть два элемента данных строки (userName и passWord), которые хранят свой массив символов вне вашего объекта и просто удерживают его как указатель на буфер. (игнорируя любые эффекты SSO на данный момент). – rakeshdn

+0

Напишите [минимальный пример] (http://meta.tex.stackexchange.com/questions/228/ive-just-been-asked-to-write-a-minimal-example-what-is-that), скомпилируйте в режиме отладки и использовать отладчик. Как программист, вы будете тратить только 10% времени на ввод кода и 90% отладки времени. – Drop

ответ

0

Ваш номер ошибки. Первое состоит в том, чтобы думать, что вы можете делать все с побитовым изображением, записанным в файл. Все данные вне вашей программы должны быть отформатированы определенным образом. Если вы хотите двоичный формат, вам понадобятся функции для форматирования и анализа a int и string. (Если нет какой-то веская причина делать в противном случае, вы, вероятно, следует использовать существующий формат: XDR , вероятно, самый простой.)

Если данные были все основные типы данных (int, char[] и т.д.), письма и чтение побитового изображения, вероятно, будет выглядеть работы. Пока вы не изменили параметры компилятора или версию или не попытались использовать для использования другой системы. Даже базовые типы требуют форматирования. (И конечно, что-нибудь с указателями нуждается в форматировании, std::string почти наверняка есть указатели на его реализации.)

И, наконец, вы используете результаты staffDetailsFile.read без тестирования удалось ли читать или нет. Это неопределенное поведение. Вероятно, ваша петля должна быть while (staffDetailsFile.read(...)). (Но вы получите только неформатированный буфер, вам все равно нужно извлечь данные. И, вероятно, вы даже не знаете, сколько байтов для чтения, , так как ваш формат для std::string, скорее всего, будет иметь переменная длина.)

0

Вы не можете писать в файл объекта типа персонала, прочитать его обратно, и ожидать, что она будет работать. Такая вещь возможна только в том случае, если ваш класс, если POD (простые старые данные). Класс вашего персонала не является POD - он содержит строковые объекты. BTW ваш тест if (temp != NULL) ошибочен - если температура не была NULL перед вызовом чтения, после нее она не будет NULL.

+0

Даже если это POD, вы не можете ожидать, что прочитаете его, если позже будете компилироваться с использованием разных опций или другой версии компилятора. –

Смежные вопросы