如何在 C++ 中的“.bin”文件中编写结构数组?
Posted
技术标签:
【中文标题】如何在 C++ 中的“.bin”文件中编写结构数组?【英文标题】:How can I write a struct array in a ".bin" file in c++? 【发布时间】:2019-12-02 17:46:07 【问题描述】:我是一个非常缺乏经验的初学者,在尝试将一些数据保存在文件中时遇到了麻烦。我的结构看起来像这样。
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.
【问题讨论】:
记事本不知道如何显示。试试 HxD @user253751 哦,谢谢。它显示得更好,但是“保存”功能仍然只写“约翰” 那是在运行程序之后,对吧?您没有使用记事本或其他任何东西保存和加载它吗?顺便说一句,十六进制代码说“乔恩”,但我认为这只是复制它的一个错误。如果你使用 ofstream 而不是 wofstream 会怎样? @user253751 是的,我删除了“datos.bin”,然后再次运行程序,然后程序创建了文件。它仍然只打印 [0] 元素的 .Name 。 (对不起,如果我没有很好地解释自己,我的英语不是很好) 通常存储句柄(例如 HWND、HBITMAP)是没有意义的。相反,您应该存储句柄代表的任何数据。因此,如果您有图像句柄,请存储图像,而不是该图像的句柄。 【参考方案1】:首先,除非您需要在堆栈上传递指针或构造数组,否则最好使用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 序列化的信息可以在here 找到。使用这种方法,您可以获得额外的好处,即能够为更多操作系统输出任何文件类型,而不仅仅是 Windows(增加了可移植性)。然而,信息可能没有被加密,所以也许加密/解密算法可以环绕这些函数。希望这至少可以帮助您找到一个起点。
【讨论】:
那个方法看起来很有趣,我试试看。谢谢!以上是关于如何在 C++ 中的“.bin”文件中编写结构数组?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 C# 中的 C++ dll 中的全局变量从函数中获取返回数组?