【问题标题】:How to serialize the data in Binary I/O?如何序列化二进制 I/O 中的数据?
【发布时间】:2020-05-22 16:37:13
【问题描述】:

这是我的 C++ 类和代码片段。数据没有正确加载到对象中,这给了我内存访问错误。我能做些什么? 基类

    using namespace std;
    class Person;
    class Person
    {protected:
    int ID;
    string name;
    string address;
long int phone;
string dob;
//char pass[25];
std::string pass;

public:
Person();
Person(int ID,string name, string address, long int phone, string dob, string pass) :
    ID(ID),name(name), phone(phone),address(address),dob(dob),pass(pass)
{};

//COPY CONSTRUCTOR MUST BE CREATED INORDER TO MAKE VECTOR WORK
Person(const Person&);

virtual void showDetails() const = 0;
//MAKING THIS CLASS AN ABSTRACT CLASS

//BUNCH OF GETTERS
int getID() const;
string getName() const;
string getAddress() const;
long int getPhone() const;
string getDob() const;
string getPass() const;
void setPass(string a);
};

这是它的派生类:

      #include<iostream>
      #include"Person.h"
      #ifndef CUSTOMER_H
      #define CUSTOMER_H
      class Customer :public Person {
      private:
      float balance;

      protected:

      public:
      Customer() :Person(), balance(0) {}
      Customer(int ID,std::string name,std::string address,long int phone, string dob,std::string 
      pass,float balance):
      Person(ID,name,address,phone,dob,pass),balance(balance){};
      //Customer(int ID, const char* name, const char* address, long int phone, string dob, const 
      char* pass, float balance) :
      //  Person(ID, name, address, phone, dob, pass), balance(balance) {};

//COPY CONSTRUCTOR MUST BE PROVIDED, ELSE VECTOR WONT WORK
Customer(const Customer& other) :Person(other) {
    this->balance = other.balance;
}
float getBalance() const;
void showDetails() const;
// void setValues();
void deposit(float);
void withdraw(float);
};
#endif

我遇到了数据没有从文件正确复制到向量的问题:这是文件处理的实现:

    void Controller::displayCustomers()
{

vector<Customer> custVector;
Customer cust;
fstream fin("customer.txt", ios::binary | ios::in);
while (fin.read(reinterpret_cast<char*>(&cust), sizeof(cust)));
    {
        custVector.push_back(cust);
    }
fin.close();
cout << "ID\tNAME\tADDRESS\tPHONE\t\tDOB\tPASSWORD\tBALANCE" << endl;
for (vector<Customer>::iterator itr = custVector.begin();
    itr != custVector.end(); ++itr)
{
    cout << itr->getID() << "\t" << itr->getName() << "\t" << itr->getAddress() << "\t"
        << itr->getPhone() << "\t" << itr->getDob() << "\t" << itr->getPass() <<
        "\t" << itr->getBalance() << endl;
}
cout << endl;
 }

构造函数运行的不仅仅是数据成员,并且在访问向量成员时会出现内存访问错误。最佳做法应该是什么?

【问题讨论】:

  • while (fin.read(reinterpret_cast&lt;char*&gt;(&amp;cust), sizeof(cust))); 不能使用像 std::stringstd::vector 这样的非 POD 类来完成。此外,.txt 不是二进制数据扩展的好选择,因为数据不是文本,不应作为文本文件读取。此外,如果您使用相同的技术写入数据也是错误的。您最终将指针存储在数据文件中,而不是指针指向的实际字符串。

标签: c++ serialization file-handling


【解决方案1】:

您不能使用二进制 I/O 直接读取或写入包含 std::string 的对象。所以这段代码是错误的。

fin.read(reinterpret_cast<char*>(&cust), sizeof(cust))

最佳实践完全取决于您要达到的目标。必须使用二进制 I/O 吗?可以换班吗?您是否正在尝试对您的文件进行索引访问?

要获得更好的建议,您需要说明您实际想要达到的目标。目前任何人都可以说这段代码是错误的。

您可能只是选择了二进制 I/O,因为您认为它是最简单的。如果是这种情况,那么您可能应该放弃它并切换到文本 I/O。但我不会根据猜测给出建议。你需要在这里说出你想要做什么。

附录

我注意到这是你的代码

//char pass[25];
std::string pass;

如果您坚持这样做,并替换了类中的所有字符串,那么您可能会发现您的读写代码开始工作了。这就是所谓的 plain old data (POD) 类。可以按照您尝试的方式读取和写入 POD 类。

请注意,您还必须删除任何虚函数,因此 POD 类可能不是一个好主意。

【讨论】:

  • 我正在做一个银行管理项目。我必须在这个项目中实现文件处理来维护记录
  • 我认为这是一个学术练习。您刚刚评论的内容都没有意味着您需要一个二进制文件。所有这些都可以使用普通的文本文件。
  • @drescherjm 是的,这是一项学术练习。更多的是期末项目。现在最好的实现应该是什么?
  • @AliKamran -- 底线是您将 data 写入文件,而不是类对象的字节。然后在读取时,您从文件中读取数据,并根据该数据重新创建对象。
  • 我的建议是为您的班级实施 operator> 并使用普通文本文件。见这里:https://isocpp.org/wiki/faq/serialization#serialize-text-format
猜你喜欢
  • 2015-01-29
  • 1970-01-01
  • 2016-06-15
  • 2011-05-09
  • 1970-01-01
  • 2012-05-05
  • 2016-09-15
  • 1970-01-01
  • 2023-04-01
相关资源
最近更新 更多