Как написать и прочитать класс из двоичного файла в C ++ - PullRequest
0 голосов
/ 16 марта 2020

Я изучаю fstream на c ++, и мне нравится писать класс в двоичном формате, а затем извлекать его. и, конечно, все пошло ужасно неправильно.

вот класс

class Student
{
private:
    const char* name;
    int age;
public:
    Student()
    {

    };
    Student(const char* name, int age) : name{ name }, age{ age }{};
    void display()
    {
        std::cout << "name : " << this->name << std::endl << "age : " << this->age << std::endl;
    }
};

класс письма (который, я думаю, работает)

void writeDatabase()
{
    Student jack("jack", 21);
    std::ofstream file;
    file.open("data.dat", std::ios::binary);
    if (file.is_open())
    {
        file.write(reinterpret_cast<char*>(&jack), sizeof(jack));
        std::cout << "wrote to file";
    }
    else
    {
        std::cout << "error opening file when writing to database\n";
    }
    file.close();
}

, где я застрял

void readData()
{
    Student st;
    std::ifstream file;
    file.open("data.dat", std::ios::binary);
    if (file.is_open())
    {
        std::cout << "opened file\n";
        file.read(reinterpret_cast<char*>(&st), sizeof(st));
        st.display();
        file.close();
    }
    else
    {
        std::cout << "error opening file when reading\n";
    }
}

1 Ответ

3 голосов
/ 16 марта 2020

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

В вашем классе есть член данных name, то есть const char *. Это указатель на какое-то место в памяти, которое содержит имя. Когда вы используете функцию write для записи данных с вашего типа на диск, он хранит этот указатель где-то на диске. Когда вы затем загружаете данные с диска, он перезагружает этот указатель.

Проблема в том, что указатель не то, что вы хотите сохранить. Если вы перезагрузите указатель с диска, он будет указывать на то же место в памяти, что и раньше, но нет никаких оснований подозревать, что вы найдете имя студента в памяти в том месте, куда он указывает. Если вы закрыли программу, а затем снова открыли ее, вы не должны видеть никакой памяти из предыдущего запуска.

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

Надеюсь, это поможет!

...