Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
448 views
in Technique[技术] by (71.8m points)

serialization - c++ Read/Write class from/to binary file

I need to write a class to a binary file, and then I need to read it back.

I have Triangle and BinaryFile classes, and some other classes. I am not sure if I am writing incorrectly or reading incorrectly. An error occurs when reading. After debugging, I think that it gets inappropriate data for my private variables. I will be very glad if someone can give me some advice on how to make it work properly.

I wasn't sure if I should paste the whole code or not, so I will give you a short snippet of code. Just in case, here is a download link for my source code:

https://my.pcloud.com/publink/show?code=XZJ7CYZbsLWLglqV5p83csijcEUTFqqpM3k

I am a newbie in programming and I don't speak English very well, so I apologize in advance for my mistakes.

class Point
{
private:
    int x;
    int y;
};

class Figure
{
private:
    string name;
    string type;
};

class Triangle: public Figure
{
private:
    Point p1, p2, p3;
};

class BinaryFile
{
private:
    string FileName;
    fstream File;
public:
    //...
    void AddNewFigure(istream& stream)
    {       
        File.open(this->FileName, ios::binary | ios::app);
        if(!this->File)
        {
            cerr<<"File error <"<<this->FileName<<">
";
            exit(1);
        }
        Triangle fig;
        fig.MakeNewFigure(stream);
        File.write((char*)&fig, sizeof(Triangle));
        File.close();
    }

    Triangle GetTriangle()
    {
        Triangle trig;
        Point p;
        string str(""); int x(0);
        File.open(this->FileName, ios::binary | ios::in);
        if(!this->File)
        {
            cerr<<"File error <"<<this->FileName<<">
";
            exit(1);
        }
        File.read((char*)&trig, sizeof(Triangle));
        File.close();
        return trig;
    }
};
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The answer depends on whether you are just doing this to learn how files work or whether saving to the file is just incidental and you don't care how it works.

If you just want to get the stuff to save and restore and you don't care how it works then use a third party library. There are many many of them.

If you want to learn how to read and write things to files then you will need to make your own read and write functions. I have made a sample program that will explain how it works:

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

class Point
{
private:
    int x;
    int y;
public:
    Point():x(0),y(0){}
    Point(int x,int y):x(x),y(y){}

    void write(std::ostream& f)
    {
        // We can just write out the bytes for x and y because
        // they are primitive types stored in the class
        f.write( (char*)&x, sizeof(x) );
        f.write( (char*)&y, sizeof(y) );
    }
    void read(std::istream& f)
    {
        // We can just read the bytes directly into x and y because
        // they are primitive types stored in the class
        f.read( (char*)&x, sizeof(x) );
        f.read( (char*)&y, sizeof(y) );
    }
};

class Figure
{
private:
    std::string name;
    std::string type;
public:
    Figure(){}
    Figure(std::string name,std::string type):name(name),type(type){}

    void write(std::ostream& f)
    {
        size_t size;

        // we need to store the data from the string along with the size
        // because to restore it we need to temporarily read it somewhere
        // before storing it in the std::string (istream::read() doesn't
        // read directly to std::string)

        size = name.size();
        f.write( (char*)&size, sizeof(size_t) );
        f.write( (char*)name.c_str(), size );

        size = type.size();
        f.write( (char*)&size, sizeof(size_t) );
        f.write( (char*)type.c_str(), size );
    }
    void read(std::istream& f)
    {
        size_t size;
        char *data;

        // when we read the string data we need somewhere to store it
        // because we std::string isn't a primitive type.  So we read
        // the size, allocate an array, read the data into the array,
        // load the std::string, and delete the array

        f.read( (char*)&size, sizeof(size) );
        data = new char[size+1];
        f.read( data, size );
        data[size]='';
        name = data;
        delete data;

        f.read( (char*)&size, sizeof(size) );
        data = new char[size+1];
        f.read( data, size );
        data[size]='';
        type = data;
        delete data;
    }
};

class Triangle: public Figure
{
private:
    Point p1, p2, p3;
public:
    Triangle(){}
    Triangle(Point x,Point y,Point z,Figure f):p1(x),p2(y),p3(z),Figure(f){}


    void write(std::ostream& f)
    {
        // First write the base class then write the members of this class
        Figure::write(f);
        p1.write(f);
        p2.write(f);
        p3.write(f);
    }
    void read(std::istream& f)
    {
        // First read the base class then read the members of this class
        Figure::read(f);
        p1.read(f);
        p2.read(f);
        p3.read(f);
    }
};

class BinaryFile
{
private:
    std::string FileName;
    std::fstream File;
public:
    BinaryFile(std::string FileName) : FileName(FileName) {};
    void WriteTriangle()
    {
        File.open(FileName, std::ios::binary | std::ios::out);
        if(!File)
        {
            std::cerr<<"File error <"<<FileName<<">
";
            exit(1);
        }
        Triangle trig({1,2},{3,4},{5,6},{"name","type"}); // something new
        trig.write(File);
        File.close();
    }

    Triangle ReadTriangle()
    {
        File.open(FileName, std::ios::binary | std::ios::in);
        if(!File)
        {
            std::cerr<<"File error <"<<FileName<<">
";
            exit(1);
        }
        Triangle trig; // default values
        trig.read(File);
        File.close();
        return trig;
    }
};

main()
{
    BinaryFile bin("file.bin");
    bin.WriteTriangle();
    Triangle trig = bin.ReadTriangle();
    // at this point trig has the values we stored
    return 0;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...