如何在 c++ 的".bin"文件中编写结构数组?

How can I write a struct array in a ".bin" file in c++?

本文关键字:结构 数组 bin c++ 文件      更新时间:2023-10-16

我是一个非常没有经验的初学者,在尝试将一些数据保存在文件中时遇到了麻烦。我的结构看起来像这样。

struct Appointment {
wchar_t Name[50]; //name of the patient
wchar_t Age[3]; //age of the patient
HWND hwdnd_img; //handler of the image of the patient to  be displayed in windows
HBITMAP hbitimg; //hbitmap of the image of the patient
wchar_t wchr_Dirimg[MAX_PATH] = L""; // directory of the image of patient
};

这是我尝试编写的Appointment类型的数组:

Appointment  Arraytosave[5];

假设它有以下数据:

Arraytosave[0].Name = L"John";   
Arraytosave[0].Age = L"23";
Arraytosave[0].hwdnd_img = example bitmap hwnd;
Arraytosave[0].hbitimg = example hbitmap data;
Arraytosave[0].wchr_Dirimg = L"C:\Example path";

这是我编写它的代码:

void Save(Appointment* Arraytosave, int elements_in_array) {
wofstream outputF("datos.bin", ios::binary | ios::trunc);
if (!outputF.is_open()) {
MessageBox(NULL, L"Cannot open file", L" SAVE_FILE FAILED", MB_ICONERROR);
}
else {
if (!(elements_in_array== 0)) {
for (int i = 0; i < elements_in_array; i++) {
int sizeName= sizeof(Arraytosave[i].Name);
int sizeAge= sizeof(Arraytosave[i].Age);
int sizehwdnd_img = sizeof(Arraytosave[i].hwdnd_img);
int sizehbitimg = sizeof(Arraytosave[i].hbitimg);
int sizewchr_Dirimg = sizeof(Arraytosave[i].wchr_Dirimg);
outputF.write(reinterpret_cast<wchar_t*>(&Arraytosave[i].Name), sizeName);

outputF.write(reinterpret_cast<wchar_t*>(&Arraytosave[i].Age), sizeAge);

outputF.write(reinterpret_cast<wchar_t*>(&Arraytosave[i].hwdnd_img), sizehwdnd_img );
outputF.write(reinterpret_cast<wchar_t*>(&Arraytosave[i].hbitimg), sizehbitimg );
outputF.write(reinterpret_cast<wchar_t*>(&Arraytosave[i].wchr_Dirimg), sizewchr_Dirimg );
}
outputF.write(reinterpret_cast<wchar_t*>(elements_in_array), sizeof(int));
outputF.close();
}
}

但是当我用记事本检查文件datos.bin时,它只显示Arraytosave[0].Name,没有其他内容。

John

编辑

好的,所以我下载了"HxD"程序,它像这样显示它

offset(h) 00 01 02 03 04 05 06 07 08 0A 0B 0C 0D 0E 0F  Decoded text
00000000  4A 6F 68 6E 00                                John.

首先,除非你需要在堆栈上传递指针或构造数组,否则通常最好使用std::vector<Ty>(其中Ty是你的数组类型(。向量是一个对象,因此还包含指向所用元素末尾和容器末尾的指针。如果你需要访问一个元素,你仍然可以使用[]运算符,它会同样快(不做边界检查,类似于数组(。此数据类型位于<vector>标头中。

问题的下一部分是保存自定义类型的数据。为此,Boost 库内置了一个序列化功能。要使用它,请#include <boost/archive/text_iarchive.hpp>#include <boost/archive/text_oarchive.hpp>(从提升的 CMD 窗口运行bootstrap.bat后(。

下面是一个使用示例:如果我正在制作游戏并想要保存玩家状态,我可以使用 Boost 执行此操作,如下所示

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <fstream>
#include <string>
#include <vector>
class Player
{
private:
std::string name;
std::vector<int> lucky_numbers;
public:
Player(/* Args here */) { /* Stuff here */ }
friend class boost::serialization::access;  // Required for Boost
template <typename Archive>  // Template function required
void serialize(Archive& ar, unsigned version)  // These 2 params required
{
// '&' is a Boost overloaded operator for either '<<' or '>>', 
// depending on the situation
ar & name;
ar & lucky_numbers;
}
};
void save(const Player& player_to_save)
{
std::ofstream save_filestream(/* rel. path of file */);
if (save_filestream.is_open())
{
// text_oarchive takes std::ofstream as parameter
boost::archive::text_oarchive save_file(save_filestream);
save_file << player_to_save;  // Player is serialized into this file
}
}
void load(Player& player_to_load)
{
std::ifstream load_filestream(/* rel. path of file */);
if (load_filesteram.is_open())
{
boost::archive::text_iarchive load_file(load_filestream);
// Below, serialized player is loaded into instance of class
load_file >> player_to_load;
}
}

有关 Boost 序列化的更多信息,请参见此处。使用此方法,您还有一个额外的好处,即能够输出到更多操作系统的任何文件类型,而不仅仅是 Windows(增加了可移植性(。但是,信息可能未加密,因此也许加密/解密算法可以围绕这些功能。希望这至少可以帮助您找到一个起点。