[英]How can I write a struct array in a ".bin" file in c++?
我是一個非常缺乏經驗的初學者,在嘗試將一些數據保存在文件中時遇到了麻煩。 我的結構看起來像這樣。
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(增加了可移植性)。 然而,這些信息可能沒有加密,所以也許加密/解密算法可以圍繞這些功能。 希望這至少可以幫助您找到一個起點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.