C ++ повреждение данных при чтении файла

0

Я пишу программу c++ для записи данных в файл в двоичном режиме и чтения из файла. Я пишу объект и читаю объект. Проблема, с которой я столкнулась, заключается в том, что когда я пишу в файл и читаю его в этом экземпляре, не закрывая программу, он работает с файлом. Но после того, как программа завершает выполнение и комментирует блок кода записи и пытается прочитать уже написанный файл, я получаю crappy output.

Я не могу понять, что происходит не так.

Вот код:

#include <fstream.h>
#include <string.h>

class Student{
    protected:
        char *Name, *Sub_code;
        int Roll;
    public:
        Student(){}
};

class Details:private Student{
    private:
        char *Sub_Name;
        int internal_marks, external_marks;
        /*Methods*/
        void setName();
        void setRoll();
        void setSubCode();
        void setSubName();
        void setInternalMarks();
        void setExternalMarks();
    public:
        Details(){
         Name = new char[1];
            Sub_code = new char[1];
            Sub_Name = new char[1];
            Name[0] = '\0';
            Sub_code[0] = '\0';
            Sub_Name[0] = '\0';
            internal_marks = 0;
            external_marks = 0;
            Roll = 0;
        }
        void setDetails();
        void getDetails();
        static void writeDetails(Details detail);
        static void readDetails();
};

void Details::setName(){
    cout<<"Enter Student Name : ";
    char tmp[100];
    tmp[0] = '\0';
    cin>>tmp;
    int len = strlen(tmp);
    Name = new char[len];
    strcpy(Name,tmp);
}

void Details::setRoll(){
    cout<<"Enter Roll Number : ";
    cin>>Roll;
}

void Details::setSubCode(){
    cout<<"Enter Subject Code : ";
    char tmp[100];
    tmp[0] = '\0';
    cin>>tmp;
    int len = strlen(tmp);
    Sub_code = new char[len];
   strcpy(Sub_code,tmp);
}

void Details::setSubName(){
    cout<<"Enter Subject Name : ";
    char tmp[100];
    tmp[0] = '\0';
    cin>>tmp;
    int len = strlen(tmp);
    Sub_Name = new char[len];
   strcpy(Sub_Name,tmp);
}

void Details::setInternalMarks(){
    cout<<"Enter internal marks : ";
    cin>>internal_marks;
}

void Details::setExternalMarks(){
    cout<<"Enter external marks : ";
    cin>>external_marks;
}

void Details::setDetails(){
     setName();
     setRoll();
     setSubCode();
     setSubName();
     setInternalMarks();
     setExternalMarks();
}

void Details::getDetails(){
    cout<<Name<<"\t\t";
    cout<<Roll<<"\t\t";
    cout<<Sub_code<<"\t\t";
    cout<<Sub_Name<<"\t";
    cout<<internal_marks<<"\t";
    cout<<external_marks<<"\t\n";
}

void Details::writeDetails(Details detail){
    ofstream os("StudentsRecord.dat", ios::binary|ios::ate);
    os.write(reinterpret_cast <char *>(&detail),sizeof(detail));
    os.close();
}

void Details::readDetails(){
    Details detail;
    ifstream is("StudentsRecord.dat", ios::binary|ios::in|ios::beg);
    cout<<"Name\tRoll\tSubject Code\tSubject Name\tInternal marks\tExternal Marks\n";
    while (is.read(reinterpret_cast<char *>(&detail), sizeof(detail))){
        detail.getDetails();
    }
    is.close();
}

int main(){
    Details y,x;
    /*for(int i = 0; i < 2; i++){
        x.setDetails();
        Details::writeDetails(x);
    }*/
    Details::readDetails();
    return 0;
}

Прокомментированный код в main() - это блок, который используется для записи данных в файл. Вот пример снимка экрана, который я получаю. Изображение 174551

С уважением Приябрата

Теги:
file-io

1 ответ

2

Класс Detail имеет char* внутри. Когда вы пишете его в файл, вы записываете фактический адрес указателя строки, а не фактическую строку. Когда вы читаете его обратно в той же программе, он работает, потому что данные все еще там.

Когда вы повторно запускаете свою программу, вы получаете мусор, потому что этот указатель не находится в какой-то случайной части памяти.

Вы должны использовать библиотеку, которая выполняет сериализацию для вас. Это трудно сделать правильно. Взгляните на https://code.google.com/p/protobuf/, но я уверен, что есть и другие.

  • 0
    Я понимаю причину, но будет трудно интегрировать protobuf в мой код, плюс это будет неприемлемо в моем колледже. Мне нужно решить эту проблему, используя (если существует) альтернативный способ.
  • 0
    @Priyabrata Тогда вам нужно разработать способ кодирования всех указателей в вашей структуре. Вы должны убедиться, что в файл записаны фактические данные (нигде нет указателей). Protobuffer - это всего лишь пример способа достижения этого, но, безусловно, не единственный.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню