如何在 C++ 中使用二进制文件将包含另一个对象的向量的对象保存到文件中并从文件中读回?
How do I save an object containing a vector of another object into file and read back from file using binary files in C++?
这是我读写向量的代码;执行时我没有收到任何错误,但每当我从中读回时;它给出整数的随机值而不是 50 和 100。我做错了什么?
我在另一个对象中使用了矢量对象,我正在尝试使用对象的二进制归档来归档它。
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
class Rest{
int value;
public:
void setvalue(int value){this->value=value;}
int getvalue(){return value;}
};
class Admin{
vector<Rest> restaurant;
public:
Admin(){}
void setValue(int value){
Rest obj1;
Rest obj2;
obj1.setvalue(value);
obj2.setvalue(value+50);
restaurant.push_back(obj1);
restaurant.push_back(obj2);
}
vector<Rest> getRestFromFile(){
Admin obj;
fstream getsavedvector("Testsave.BIN", ios::in | ios::binary);
getsavedvector.read(reinterpret_cast<char*> (&obj), sizeof(obj));
getsavedvector.close();
return obj.getRest();
}
void setRestVectorToFile(Admin obj){
fstream savevector("Testsave.BIN", ios::out | ios::binary);
savevector.write(reinterpret_cast<char*> (&obj),sizeof(obj));
savevector.close();
}
void setRestVector(vector<Rest> restaurant){
for(int i=0;i<restaurant.size();i++){
this->restaurant.push_back(restaurant[i]);
}
}
vector<Rest> getRest(){
return this->restaurant;
}
void Display(){
for(auto v: restaurant){
cout<<v.getvalue()<<endl;
}
}
};
int main()
{
Admin obj;
obj.setValue(50);
obj.setRestVectorToFile(obj);
Admin obj2;
obj2.setRestVector(obj2.getRestFromFile());
obj2.Display();
}
基本上你做错的是你不能只将 C++ 对象转换为 char *
并将一些字节转储到磁盘上并期望它能工作。现在 是 将在某些有限的情况下工作,例如当您只编写原始对象(如整数或仅包含整数或类似内容的结构)时,但它不会在更多情况下工作复杂的东西,比如向量。执行此操作的正确方法是想出或使用现有的 Serialization 格式,以获得正确的矢量编码,您可以 encode/decode 在写入文件或从文件读取之间。
您可以在这种情况下使用一个非常简单的方案,无需太多更改,即首先存储向量的长度,然后按顺序存储每个元素。这很容易读写。如果你想要一个更通用的解决方案,你会想要查看像 JSON、msgpack、XML 这样的格式,甚至像 SQLite 或 PostgreSQL 这样的数据库管理系统。哪个是“正确”的选择取决于您的应用程序,在这种情况下,尤其是如果您只是学习读写文件,您可以将自己的简单格式作为练习。
这是我读写向量的代码;执行时我没有收到任何错误,但每当我从中读回时;它给出整数的随机值而不是 50 和 100。我做错了什么?
我在另一个对象中使用了矢量对象,我正在尝试使用对象的二进制归档来归档它。
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
class Rest{
int value;
public:
void setvalue(int value){this->value=value;}
int getvalue(){return value;}
};
class Admin{
vector<Rest> restaurant;
public:
Admin(){}
void setValue(int value){
Rest obj1;
Rest obj2;
obj1.setvalue(value);
obj2.setvalue(value+50);
restaurant.push_back(obj1);
restaurant.push_back(obj2);
}
vector<Rest> getRestFromFile(){
Admin obj;
fstream getsavedvector("Testsave.BIN", ios::in | ios::binary);
getsavedvector.read(reinterpret_cast<char*> (&obj), sizeof(obj));
getsavedvector.close();
return obj.getRest();
}
void setRestVectorToFile(Admin obj){
fstream savevector("Testsave.BIN", ios::out | ios::binary);
savevector.write(reinterpret_cast<char*> (&obj),sizeof(obj));
savevector.close();
}
void setRestVector(vector<Rest> restaurant){
for(int i=0;i<restaurant.size();i++){
this->restaurant.push_back(restaurant[i]);
}
}
vector<Rest> getRest(){
return this->restaurant;
}
void Display(){
for(auto v: restaurant){
cout<<v.getvalue()<<endl;
}
}
};
int main()
{
Admin obj;
obj.setValue(50);
obj.setRestVectorToFile(obj);
Admin obj2;
obj2.setRestVector(obj2.getRestFromFile());
obj2.Display();
}
基本上你做错的是你不能只将 C++ 对象转换为 char *
并将一些字节转储到磁盘上并期望它能工作。现在 是 将在某些有限的情况下工作,例如当您只编写原始对象(如整数或仅包含整数或类似内容的结构)时,但它不会在更多情况下工作复杂的东西,比如向量。执行此操作的正确方法是想出或使用现有的 Serialization 格式,以获得正确的矢量编码,您可以 encode/decode 在写入文件或从文件读取之间。
您可以在这种情况下使用一个非常简单的方案,无需太多更改,即首先存储向量的长度,然后按顺序存储每个元素。这很容易读写。如果你想要一个更通用的解决方案,你会想要查看像 JSON、msgpack、XML 这样的格式,甚至像 SQLite 或 PostgreSQL 这样的数据库管理系统。哪个是“正确”的选择取决于您的应用程序,在这种情况下,尤其是如果您只是学习读写文件,您可以将自己的简单格式作为练习。