在二进制文件 C++ 中写入和加载结构向量
Write and load vector of structs in a binary file c++
我真的需要你的帮助。我的代码中有以下结构:
struct Field{
char name[20];
int type;
int length;
};
struct Record{
vector<Field> structure;
vector<string> info;
};
我想做的是将我的结构 Record 的向量存储在一个二进制文件中并成功地加载它。问题是我的结构内部有两个向量,它们给我带来了一些麻烦。你能帮帮我吗?
您基本上只是编写将结构写入流的函数。如果它是 POD,首先你写下结构的大小。
如果不是 POD,则写入每个元素的大小,然后写入该元素的数据。
下面你可以看到对于writevecfield,它首先写入了向量的大小。然后它将整个 POD 结构写入流。 writesvecstring 首先写入向量的大小。然后它遍历向量并写入:每个字符串的大小及其内容。
阅读,恰恰相反。 readvecfield 从文件中读取向量的大小,因为它是第一个写入的东西。读取后,我们调整向量的大小并将“字段”结构的“大小”数量读入新向量。
要读取字符串,我们也做相反的事情。 readvecstring 首先从文件中读取向量的大小。它将向量的大小调整为读取大小。接下来它循环“大小”次数,因为这是文件中的字符串数量。
然后我们读取字符串的大小,调整字符串的大小并将内容读入该字符串。然后我们将其添加到向量并移动到下一个字符串:首先读取大小,调整字符串大小,读取内容,添加到向量..
#include <fstream>
#include <vector>
#include <iostream>
#include <sstream>
using namespace std;
struct Field
{
char name[20];
int type;
int length;
};
struct Record
{
vector<Field> structure;
vector<string> info;
};
void writevecfield(ostream& os, const vector<Field> &vec)
{
typename vector<Field>::size_type size = vec.size();
os.write((char*)&size, sizeof(size));
os.write((char*)&vec[0], vec.size() * sizeof(Field));
}
void readvecfield(istream& is, vector<Field> &vec)
{
typename vector<Field>::size_type size = 0;
is.read((char*)&size, sizeof(size));
vec.resize(size);
is.read((char*)&vec[0], vec.size() * sizeof(Field));
}
void writevecstring(ostream& os, const vector<string> &vec)
{
typename vector<string>::size_type size = vec.size();
os.write((char*)&size, sizeof(size));
for (typename vector<string>::size_type i = 0; i < size; ++i)
{
typename vector<string>::size_type element_size = vec[i].size();
os.write((char*)&element_size, sizeof(element_size));
os.write(&vec[i][0], element_size);
}
}
void readvecstring(istream& is, vector<string> &vec)
{
typename vector<string>::size_type size = 0;
is.read((char*)&size, sizeof(size));
vec.resize(size);
for (typename vector<string>::size_type i = 0; i < size; ++i)
{
typename vector<string>::size_type element_size = 0;
is.read((char*)&element_size, sizeof(element_size));
vec[i].resize(element_size);
is.read(&vec[i][0], element_size);
}
}
void WriteRecord(ostream& out, const Record& r)
{
writevecfield(out, r.structure);
writevecstring(out, r.info);
}
void ReadRecord(istream& in, Record& r)
{
readvecfield(in, r.structure);
readvecstring(in, r.info);
}
int main()
{
Record R;
Field first = {"HELLO", 1, 20};
Field second = {"WORLD", 2, 40};
R.structure.push_back(first);
R.structure.push_back(second);
R.info.push_back("INFO FOR HELLO");
R.info.push_back("INFO FOR WORLD");
std::ofstream out("C:/Users/***/Desktop/Test.bin", std::ios::out | std::ios::binary);
WriteRecord(out, R);
out.close();
Record RR;
std::ifstream in("C:/Users/***/Desktop/Test.bin", std::ios::in | std::ios::binary);
ReadRecord(in, RR);
in.close();
for (int i = 0; i < RR.structure.size(); ++i)
{
std::cout<<"Name: "<<RR.structure[i].name<<"\n";
std::cout<<"Type: "<<RR.structure[i].type<<"\n";
std::cout<<"Length: "<<RR.structure[i].length<<"\n";
std::cout<<"INFO: "<<RR.info[i]<<"\n\n";
}
}
我是用c-like语句来处理的。关键是你只需要找到第一个vec数据的地址,而不是使用相邻的缓冲区将它们写入文件。
bool storeStructVec(FILE *fpOut, const vector<Field> &vec)
{
unsigned int nSize = vec.size();
if (nSize != fwrite(&vec[0],sizeof(Field),nSize,fpOut))
return false;
else return true;
}
我真的需要你的帮助。我的代码中有以下结构:
struct Field{
char name[20];
int type;
int length;
};
struct Record{
vector<Field> structure;
vector<string> info;
};
我想做的是将我的结构 Record 的向量存储在一个二进制文件中并成功地加载它。问题是我的结构内部有两个向量,它们给我带来了一些麻烦。你能帮帮我吗?
您基本上只是编写将结构写入流的函数。如果它是 POD,首先你写下结构的大小。
如果不是 POD,则写入每个元素的大小,然后写入该元素的数据。
下面你可以看到对于writevecfield,它首先写入了向量的大小。然后它将整个 POD 结构写入流。 writesvecstring 首先写入向量的大小。然后它遍历向量并写入:每个字符串的大小及其内容。
阅读,恰恰相反。 readvecfield 从文件中读取向量的大小,因为它是第一个写入的东西。读取后,我们调整向量的大小并将“字段”结构的“大小”数量读入新向量。
要读取字符串,我们也做相反的事情。 readvecstring 首先从文件中读取向量的大小。它将向量的大小调整为读取大小。接下来它循环“大小”次数,因为这是文件中的字符串数量。
然后我们读取字符串的大小,调整字符串的大小并将内容读入该字符串。然后我们将其添加到向量并移动到下一个字符串:首先读取大小,调整字符串大小,读取内容,添加到向量..
#include <fstream>
#include <vector>
#include <iostream>
#include <sstream>
using namespace std;
struct Field
{
char name[20];
int type;
int length;
};
struct Record
{
vector<Field> structure;
vector<string> info;
};
void writevecfield(ostream& os, const vector<Field> &vec)
{
typename vector<Field>::size_type size = vec.size();
os.write((char*)&size, sizeof(size));
os.write((char*)&vec[0], vec.size() * sizeof(Field));
}
void readvecfield(istream& is, vector<Field> &vec)
{
typename vector<Field>::size_type size = 0;
is.read((char*)&size, sizeof(size));
vec.resize(size);
is.read((char*)&vec[0], vec.size() * sizeof(Field));
}
void writevecstring(ostream& os, const vector<string> &vec)
{
typename vector<string>::size_type size = vec.size();
os.write((char*)&size, sizeof(size));
for (typename vector<string>::size_type i = 0; i < size; ++i)
{
typename vector<string>::size_type element_size = vec[i].size();
os.write((char*)&element_size, sizeof(element_size));
os.write(&vec[i][0], element_size);
}
}
void readvecstring(istream& is, vector<string> &vec)
{
typename vector<string>::size_type size = 0;
is.read((char*)&size, sizeof(size));
vec.resize(size);
for (typename vector<string>::size_type i = 0; i < size; ++i)
{
typename vector<string>::size_type element_size = 0;
is.read((char*)&element_size, sizeof(element_size));
vec[i].resize(element_size);
is.read(&vec[i][0], element_size);
}
}
void WriteRecord(ostream& out, const Record& r)
{
writevecfield(out, r.structure);
writevecstring(out, r.info);
}
void ReadRecord(istream& in, Record& r)
{
readvecfield(in, r.structure);
readvecstring(in, r.info);
}
int main()
{
Record R;
Field first = {"HELLO", 1, 20};
Field second = {"WORLD", 2, 40};
R.structure.push_back(first);
R.structure.push_back(second);
R.info.push_back("INFO FOR HELLO");
R.info.push_back("INFO FOR WORLD");
std::ofstream out("C:/Users/***/Desktop/Test.bin", std::ios::out | std::ios::binary);
WriteRecord(out, R);
out.close();
Record RR;
std::ifstream in("C:/Users/***/Desktop/Test.bin", std::ios::in | std::ios::binary);
ReadRecord(in, RR);
in.close();
for (int i = 0; i < RR.structure.size(); ++i)
{
std::cout<<"Name: "<<RR.structure[i].name<<"\n";
std::cout<<"Type: "<<RR.structure[i].type<<"\n";
std::cout<<"Length: "<<RR.structure[i].length<<"\n";
std::cout<<"INFO: "<<RR.info[i]<<"\n\n";
}
}
我是用c-like语句来处理的。关键是你只需要找到第一个vec数据的地址,而不是使用相邻的缓冲区将它们写入文件。
bool storeStructVec(FILE *fpOut, const vector<Field> &vec)
{
unsigned int nSize = vec.size();
if (nSize != fwrite(&vec[0],sizeof(Field),nSize,fpOut))
return false;
else return true;
}