c++将一个复杂的结构体_保存成二进制文件并读取
在 C++ 中,可以将复杂的结构体保存到二进制文件中,并从二进制文件中读取它。为了实现这一点,你可以使用文件流库。以下是一个示例,展示如何将一个复杂的结构体保存到二进制文件中,并从二进制文件中读取它。
·
在 C++ 中,可以将复杂的结构体保存到二进制文件中,并从二进制文件中读取它。为了实现这一点,你可以使用文件流库 <fstream>。以下是一个示例,展示如何将一个复杂的结构体保存到二进制文件中,并从二进制文件中读取它。
1. 示例结构体
假设我们有一个复杂的结构体 Person,其中包含一些基本数据类型和字符串。
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstring>
struct Person {
char name[50];
int age;
double height;
std::vector<int> scores;
// Method to serialize the structure to a binary stream
void serialize(std::ofstream& ofs) const {
ofs.write(name, sizeof(name));
ofs.write(reinterpret_cast<const char*>(&age), sizeof(age));
ofs.write(reinterpret_cast<const char*>(&height), sizeof(height));
size_t scores_size = scores.size();
ofs.write(reinterpret_cast<const char*>(&scores_size), sizeof(scores_size));
ofs.write(reinterpret_cast<const char*>(scores.data()), scores.size() * sizeof(int));
}
// Method to deserialize the structure from a binary stream
void deserialize(std::ifstream& ifs) {
ifs.read(name, sizeof(name));
ifs.read(reinterpret_cast<char*>(&age), sizeof(age));
ifs.read(reinterpret_cast<char*>(&height), sizeof(height));
size_t scores_size;
ifs.read(reinterpret_cast<char*>(&scores_size), sizeof(scores_size));
scores.resize(scores_size);
ifs.read(reinterpret_cast<char*>(scores.data()), scores_size * sizeof(int));
}
};
保存结构体到二进制文件
void savePersonToFile(const Person& person, const std::string& filename) {
std::ofstream ofs(filename, std::ios::binary);
if (!ofs) {
std::cerr << "Error opening file for writing: " << filename << std::endl;
return;
}
person.serialize(ofs);
ofs.close();
}
从二进制文件读取结构体
Person loadPersonFromFile(const std::string& filename) {
Person person;
std::ifstream ifs(filename, std::ios::binary);
if (!ifs) {
std::cerr << "Error opening file for reading: " << filename << std::endl;
return person;
}
person.deserialize(ifs);
ifs.close();
return person;
}
示例用法
int main() {
Person person;
std::strcpy(person.name, "John Doe");
person.age = 30;
person.height = 5.9;
person.scores = {85, 90, 78};
std::string filename = "person.dat";
// Save to binary file
savePersonToFile(person, filename);
// Load from binary file
Person loaded_person = loadPersonFromFile(filename);
// Display loaded person information
std::cout << "Name: " << loaded_person.name << std::endl;
std::cout << "Age: " << loaded_person.age << std::endl;
std::cout << "Height: " << loaded_person.height << std::endl;
std::cout << "Scores: ";
for (int score : loaded_person.scores) {
std::cout << score << " ";
}
std::cout << std::endl;
return 0;
}
解释
-
序列化和反序列化方法:
serialize方法将结构体的各个成员写入到二进制文件中。deserialize方法从二进制文件中读取结构体的各个成员。
-
文件流:
- 使用
std::ofstream打开文件进行写操作,并设置为二进制模式(std::ios::binary)。 - 使用
std::ifstream打开文件进行读操作,并设置为二进制模式(std::ios::binary)。
- 使用
-
字符串和动态数组的处理:
std::vector的大小和数据都需要序列化和反序列化,因为它是一个动态数组。char[]字符数组可以直接写入和读取。
通过上述方法,你可以将复杂的结构体保存到二进制文件中,并从二进制文件中读取它。这种方法可以确保结构体的数据被正确保存和恢复。
2. 运行结果

3. 其它实例
使用c语言的形式,混合的写入 char[], int, 自定义结构体
#include <stdio.h>
#include <memory>
#include <iostream>
#include <cstring>
#include <algorithm>
// 定义结构体
typedef struct {
float a;
float b;
float c;
int x;
int y;
char f1[3];
char f2[3];
char f3[3];
} MyStruct;
int main() {
const char *filename = "data_john2.bin";
FILE *file;
// 打开文件以写入二进制数据
file = fopen(filename, "wb");
if (file == NULL) {
perror("Error opening file for writing");
return 1;
}
char verbbon[8] = "v1.0";
int level = 1;
fwrite (&verbbon , sizeof(char), sizeof(verbbon), file);
fwrite (&level , sizeof(int), 1, file);
MyStruct data;
data.a = 1.1;
data.b = 1.2;
data.c = 1.3;
data.x = 10;
data.y = 92;
memset(data.f1,0,sizeof(data.f1));
memset(data.f2,0,sizeof(data.f2));
memset(data.f3,0,sizeof(data.f3));
//data.f1 = "aa";
std::string aa_str = "aa";
strncpy(data.f1, "aa", sizeof("aa")); // 注意:sizeof("aa") == 3
strncpy(data.f2, "bb", 2);
strncpy(data.f3,"cc", 2);
/*
std::string aa_str = "aa";
std::copy_n(aa_str.begin(), aa_str.size(), data.f1);
data.f1[aa_str.size()] = '\0';
std::string bb_str = "bb";
std::copy_n(bb_str.begin(), aa_str.size(), data.f2);
data.f2[bb_str.size()] = '\0';
std::string cc_str = "cc";
std::copy_n(cc_str.begin(), cc_str.size(), data.f3);
data.f3[cc_str.size()] = '\0';
*/
char data2[100];
memset(data2,0,sizeof(data2));
std::string info = "hello world";
strncpy(data2,info.c_str(), info.size());
fwrite(reinterpret_cast<char *>(&data), sizeof(MyStruct), 1, file);
fwrite (&data2 , sizeof(char), sizeof(data2), file);
// 关闭文件
fclose(file);
printf("Data saved successfully.\n");
// ===========================================
// 打开文件以读取二进制数据
file = fopen(filename, "rb");
if (file == NULL) {
perror("Error opening file for reading");
return 1;
}
char r_version[8];
int r_level;
// 为读取的数据分配内存
MyStruct *readData =reinterpret_cast<MyStruct*> (malloc(1 * sizeof(MyStruct)));
//MyStruct *readData1 =reinterpret_cast<MyStruct*> (malloc(1 * sizeof(MyStruct)));
fread(&r_version, sizeof(char), sizeof(r_version), file);
fread(&r_level, sizeof(int), 1, file);
//size_t read = fread(data, sizeof(MyStruct), count, file);
size_t read = fread(reinterpret_cast<char *>(readData), sizeof(MyStruct), 1, file);
if (read != 1) {
perror("Error reading from file");
}
char r_data2[100];
memset(r_data2,0,sizeof(r_data2));
read = fread(&r_data2, sizeof(char), sizeof(r_data2), file);
std::cout << "r_version:" << r_version << std::endl;
std::cout << "r_level:" << r_level << std::endl;
std::cout << "readData:" << readData->a << ", "
<< readData->a << ", "
<< readData->b << ", "
<< readData->c << ", "
<< readData->x << ", "
<< readData->y << ", "
<< readData->f1 << ", "
<< readData->f2 << ", "
<< readData->f3 << ", "
<< std::endl;
std::cout << "r_data2:" << r_data2 << ", " << std::endl;
// 关闭文件
fclose(file);
return 0;
}
运行结果

更多推荐
所有评论(0)