c++ - 如何将类中的类写入/读取到二进制文件C++
问题描述
我正在做一个项目,我必须编写一个包含其他三个类作为私有成员变量的类到二进制文件,然后可以将它读回到要在代码中使用的变量。代码写入文件,但我不知道它是否正在写入正确的信息,因为当我尝试读取它读取的垃圾文件时。我已经包含了我当前的设置,这看起来正确吗?如果是这样,可能出了什么问题,如果不是,我该如何解决这个问题?
如果您需要我添加任何额外的代码,请询问。另一个考虑是,用作玩家对象的成员函数的两个类继承自其他类。
if (cFile.is_open())
{
cFile.seekp(ios::beg);
for (int i = 0; i < 3; i++)
{
cFile.write(reinterpret_cast<char *>(&players[i]), sizeof(Character));
}
cFile.seekg(ios::beg);
for (int i = 0; i < 3; i++)
{
cFile.read(reinterpret_cast<char *>(&playersRead[i]), sizeof(Character));
playersRead[i].display();
}
cFile.close();
}
else
{
cout << "Error opening file." << endl;
}
我已经在这段代码上工作了几天,真的遇到了麻烦。我很感激我能得到的任何帮助,在此先感谢。
#pragma once
#include <iostream>
using std::ostream;
#include "string.h"
#include "coinPouch.h"
#include "backpack.h"
class Character
{
public:
Character();
Character(String name);
Character(String name, CoinPouch wallet, Backpack storage);
Character(const Character & copy);
~Character();
Character & operator =(const Character & rhs);
friend ostream & operator << (ostream & out, const Character & c);
void purchase(int p, int g, int s, int c);
void income(int p, int g, int s, int c);
void addPotion(const Potion & toAdd);
void checkBalance();
void checkBackpack();
void changeName(const String & newN);
void display();
String getName();
CoinPouch getWallet();
Backpack getStorage();
void setName(String name);
void setWallet(CoinPouch wallet);
void setStorage(Backpack storage);
private:
String m_name;
CoinPouch m_wallet;
Backpack m_storage;
};
#include "character.h"
using std::endl;
using std::cout;
Character::Character() : m_name("Player")
{
CoinPouch initialW;
Backpack initialS;
m_wallet = initialW;
m_storage = initialS;
}
Character::Character(String name) : m_name(name)
{
CoinPouch initialW;
Backpack initialS;
m_wallet = initialW;
m_storage = initialS;
}
Character::Character(String name, CoinPouch wallet, Backpack storage) : m_name(name), m_wallet(wallet), m_storage(storage)
{
}
Character::Character(const Character & copy) : m_name(copy.m_name), m_wallet(copy.m_wallet), m_storage(copy.m_storage)
{
}
Character::~Character()
{
}
Character & Character::operator =(const Character & rhs)
{
if (this != &rhs)
{
m_name = rhs.m_name;
m_wallet = rhs.m_wallet;
m_storage = rhs.m_storage;
}
return *this;
}
ostream & operator << (ostream & out, const Character & c)
{
out << c.m_name << ": " << endl;
out << c.m_wallet << endl;
out << c.m_storage << endl;
return out;
}
void Character::purchase(int p, int g, int s, int c)
{
m_wallet.buy(p, g, s, c);
}
void Character::income(int p, int g, int s, int c)
{
m_wallet.add(p, g, s, c);
}
void Character::addPotion(const Potion & toAdd)
{
m_storage.addPotion(toAdd);
}
void Character::checkBalance()
{
m_wallet.display();
}
void Character::checkBackpack()
{
m_storage.displayContents();
}
void Character::changeName(const String & newN)
{
m_name = newN;
}
void Character::display()
{
cout << m_name << ": " << endl;
m_wallet.display();
m_storage.displayContents();
}
String Character::getName()
{
return m_name;
}
CoinPouch Character::getWallet()
{
return m_wallet;
}
Backpack Character::getStorage()
{
return m_storage;
}
void Character::setName(String name)
{
m_name = name;
}
void Character::setWallet(CoinPouch wallet)
{
m_wallet = wallet;
}
void Character::setStorage(Backpack storage)
{
m_storage = storage;
}
#pragma once
#include <iostream>
using std::ostream;
#include "string.h"
class CoinPouch
{
public:
CoinPouch();
CoinPouch(String init);
CoinPouch(int p, int g, int s, int c);
CoinPouch(const CoinPouch & copy);
~CoinPouch();
CoinPouch & operator = (const CoinPouch & rhs);
friend ostream & operator << (ostream & out, const CoinPouch & c);
void add(int p, int g, int s, int c);
bool checkCost(int p, int g, int s, int c);
void buy(int p, int g, int s, int c);
void convertCost();
void roundUp();
void display();
int getP();
int getG();
int getS();
int getC();
private:
String m_amount;
int m_platinum;
int m_gold;
int m_silver;
int m_copper;
};
#pragma once
#include "potions.h"
class DynamicArray
{
public:
// Constructors
DynamicArray();
~DynamicArray();
DynamicArray(const DynamicArray & copy);
// Op Equals
DynamicArray & operator =(const DynamicArray & rhs);
// Insert, delete, and get elements functions
int getElements();
void Insert(const Potion & add);
void Delete(const Potion & rmv);
void display();
// Overloaded operators
Potion & operator [](int index);
friend ostream & operator << (ostream & out, const DynamicArray & d);
private:
// Member variables
Potion * m_array;
int m_elements;
// Find function
int Find(const Potion & target);
};
#pragma once
#include "string.h"
#include <iostream>
using std::ostream;
class Potion
{
public:
// Constructors
Potion();
Potion(String name, String description, String potency, String cost);
Potion & operator = (const Potion & rhs);
Potion(const Potion & copy);
// Desctructor
~Potion();
// Overloaded operators
bool operator == (const Potion & rhs) const;
friend ostream & operator << (ostream & out, const Potion & p);
// Getter functions
String getName();
String getDesc();
String getPotency();
String getCost();
int getP();
int getG();
int getS();
int getC();
// Setter functions
void setName(String name);
void setDesc(String desc);
void setPotency(String potency);
void setCost(String cost);
// Convert and display functions
void convertCost();
void display();
private:
// Strings to hold item information
String m_name;
String m_description;
String m_potency;
String m_cost;
// Ints to hold cost information
int m_platinum;
int m_gold;
int m_silver;
int m_copper;
// Logical test
bool m_isnull = false;
};
#pragma once
#include <iostream>
using std::ostream;
class String
{
public:
// Constructors
String();
String(char ch);
String(const char * str);
// Destructor
~String();
// Copy Constructor and Copy Assignment Constructor
String(const String & copy);
String & operator=(const String & rhs);
friend ostream & operator << (ostream & out, const String & s);
// Added Functionality
void display();
void upper();
void lower();
// Operator Conversion
operator char *();
operator const char *();
// Overloaded operator
bool operator == (const String & rhs) const;
private:
// Member variables
char * m_str;
int m_ischar;
};
#pragma once
#include "dynamicarray.h"
#include "coinPouch.h"
#include "string.h"
class Backpack
{
public:
Backpack();
Backpack(DynamicArray potions);
Backpack(const Backpack & copy);
~Backpack();
Backpack & operator = (const Backpack & rhs);
friend ostream & operator << (ostream & out, const Backpack & c);
void addPotion(const Potion & add);
void usePotion(const Potion & rm);
void displayContents();
private:
DynamicArray m_potions;
int m_number;
};
这是一个学校项目,我应该将 Character 类写入二进制文件以保存字符,以便在程序启动时加载它们。现在我只是想确保它们可以成功地写入和读取二进制文件,但我没有运气。
我的错,不知道要发布什么,我不想在我的文件中发布所有内容。这是字符类。让我知道还需要什么,如果有的话。
解决方案
很明显,这段代码不可能工作。
cFile.write(reinterpret_cast<char *>(&players[i]), sizeof(Character));
不管有多大sizeof(Character)
,我们都可以使用一个占用更多字节的Character
with an 。m_name
所以这段代码不可能写出角色的名字,它显然需要这样做。
在将任何内容写入文件之前,请在字节级别决定(理想情况下,记录)文件格式。确保您的代码以您记录的格式编写,并且也可以以您记录的格式读取。跳过这一步会导致痛苦,并且还会使调试变得不可能,因为您无法查看文件并将其与规范进行比较,以了解作者或阅读者是否有错。
如果您记录了播放器名称将在文件中占用的字节数,您会立即意识到您要么需要一个可变长度对象并以某种方式编码长度,要么选择一个最大大小的名称并分配这些字节数。但是因为你跳过了那个重要的步骤,所以你从来没有真正弄清楚如何将 a 写入Character
文件。
推荐阅读
- r - 在 R-Updated 中将顺序列值与特定数据框单元格相除
- flutter - Flutter 避免创建多个块
- javascript - 角度拦截器:抛出错误后保持流活动
- javascript - 如何在处理程序中使用 useEffect 或反之亦然?
- c - 我如何将斐波那契数列存储在矩阵中
- php - 错误函数已弃用 PHP 7.3.28?
- django - 我如何将内容页面呈现到另一个 html 页面
- python - 从数据框列中的列表中检查单词并在同一数据框的另一个创建列中打印单词 [Python]
- azure - 相同大小 VMSS 的不同处理器
- kivymd - 如何使用 kivymd 制作按钮以打开超链接