【问题标题】:How can I save different types of objects into a single file and read them as needed?如何将不同类型的对象保存到单个文件中并根据需要读取它们?
【发布时间】:2021-04-03 22:16:42
【问题描述】:
class Room{
    public:
        int price;
        char type[20];
        int roomNum;
        int floor_num;
        bool status; //reserved = true, not reserved = false
        Room() : price(0) , status(false){
            strcpy(type,"");
        }
        virtual ~Room(){
        }
        virtual void getData() = 0;
        bool roomStatus(){ //return true if reserved and return false if not reserved
            fstream readfile;
            readfile.open("rooms.dat", ios::in | ios::out | ios::app);
            bool flag = 0;
            if(readfile.fail()){
                cout<<"File Open Error!"<<endl;
                readfile.open("rooms.dat", ios::in | ios::out | ios::trunc);
                readfile.close();
            }
            else{
                readfile.seekg(0,ios::end);
                int n=readfile.tellg();
                n=n/sizeof(this);
                readfile.seekg(0,ios::beg);
                for(int i=1;i<=n;i++){
                    Room *temp = this;
                    readfile.read(reinterpret_cast<char *>(temp), sizeof(Room));
                    if(temp->floor_num == this->floor_num && temp->roomNum == this->roomNum){
                        flag = 1;
                        break;
                    }
                }
                readfile.close();
                return flag;
            }
        }
        void save(){
        ofstream outfile("rooms.dat", ios::app);
        outfile.write(reinterpret_cast<char *>(this), sizeof(Room));
        this->status = 1;
        outfile.close();
        cout<<"Room Reserved!"<<endl;
        }
};
class Standard : public Room{
    public:
        Standard(){
             price = 300;
             strcpy(type,"Standard");
        }
        void getData(){
        cout<<"Enter Floor Num:";
        cin>>floor_num;
        cout<<"Enter Room Num:";
        cin>>roomNum;
        }
};
class Moderate : public Room{
    public:
        Moderate(){
            price= 500;
            strcpy(type,"Moderate");
        }
        void getData(){
        cout<<"Enter Floor Num:";
        cin>>floor_num;
        cout<<"Enter Room Num:";
        cin>>roomNum;
        }
};
class Superior : public Room{
    public:
        Superior(){
            price= 1000;
            strcpy(type,"Superior");
        }
        void getData(){
        cout<<"Enter Floor Num:";
        cin>>floor_num;
        cout<<"Enter Room Num:";
        cin>>roomNum;
        }
};
class JuniorSuite : public Room{
    public:
        JuniorSuite(){
             price = 2000;
             strcpy(type,"Junior Suite");
        }
        void getData(){
        cout<<"Enter Floor Num:";
        cin>>floor_num;
        cout<<"Enter Room Num:";
        cin>>roomNum;
        }
};
class Suite : public Room{
    public:
        Suite(){
            price= 5000;
            strcpy(type,"Suite");
        }
        void getData(){
        cout<<"Enter Floor Num:";
        cin>>floor_num;
        cout<<"Enter Room Num:";
        cin>>roomNum;
        }
};

这是我的代码。我想将这些对象保存在一个名为“rooms.dat”的文件中。我想从任何对象中的完全相同的文件中读取数据。 当我从该文件读取数据时遇到问题,它不会读取该特定对象的数据。我知道这个文件中有不同类型的数据,每个对象的大小也不同,所以当它从那个文件中读取数据时,它不知道要跳过哪些数据以及读取什么。 如果您对此问题有任何有用的解决方案,请告诉我。

【问题讨论】:

  • 解决方案称为序列化。 C++ 没有内置对序列化的支持,所以要么你必须自己发明,要么你必须使用像this one这样的序列化库@
  • 如果你不想使用序列化库,那么你要做的就是在文件中保存一些信息,告诉你接下来会出现什么类型。这样你就知道要读什么样的类型了。
  • 顺便说一句,在具有虚函数的类上使用 readwrite 是不正确的。因此,您目前尝试的方式(使用读写来读取或写入整个对象)无法正常工作。
  • 代码没有说明任何理由在这里创建Room的任何子类。事实上,没有一个子类提供任何额外的字段。不知道为什么要在每个子类中重新实现getData,而不是在Room 中实现一次。总而言之,您最好添加一个Room(const char* aType, int aPrice) 构造函数,并在必要时为StandardSuite 等创建工厂方法。在这种情况下,这将完全解决问题,因为您在阅读时不再需要区分类型。
  • 因为我想做这样的事情:cout&lt;&lt;"1. Standard"&lt;&lt;endl; cout&lt;&lt;"2. Moderate"&lt;&lt;endl; cout&lt;&lt;"3. Superior"&lt;&lt;endl; cout&lt;&lt;"4. Junior Suite"&lt;&lt;endl; cout&lt;&lt;"5. Suite"&lt;&lt;endl; cout&lt;&lt;"Enter Room Type:"; int type; cin&gt;&gt;type; if(type==1) room = new Standard; else if(type==2) room = new Moderate; else if(type==3) 如果我做错了什么,请告诉我,因为我是这个概念的新手。

标签: c++ oop fstream file-handling ifstream


【解决方案1】:

试试这个:

ofstream out;
out.open("rooms.txt");
out << obj1 << obj2 << ... << endl;

ifstream in;
in.open("rooms.txt");
in >> obj1 >> obj2 >> ...;

或者你如果你想使用仍然 cin 和 cout:

freopen ("rooms.txt","w",stdin);
freopen ("rooms.txt","w",stdout); 

【讨论】:

    猜你喜欢
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    相关资源
    最近更新 更多