将结构写入 .txt 文件
writing struct to .txt file
我正在尝试使用 boost 将我的结构存储到 txt 文件中,但无法做到。我正在使用提升库。
示例结构
struct Frame
{
uint32_t address{ 0 };
uint16_t marks{ 0 };
uint16_t age{ 0 };
char gender{ 'M' };
std::string userName;
};
对于二进制有简单的代码
boost::archive::binary_oarchive ar(ofs, boost::archive::no_header);
ar << boost::serialization::make_binary_object(&f, sizeof(Frame));
假设文件是用 fstream 对象打开的,'f' 是 'Frame'
的对象
我想知道有没有类似的写结构到txt文件的方法,不想一一写数据类型。
假设我们不知道结构内部数据类型的types/number。
正如其他人所评论的那样,您将必须提供序列化助手来告诉 Boost 如何进行成员序列化。
如果你只有这样的聚合,你可以在一定程度上自动生成这个函数 Boost PFR:
pfr::for_each_field(s, [&](auto&& f) { ar & f; });
这是一个例子:
namespace MyLib {
struct Frame {
uint32_t address{0};
uint16_t marks{0};
uint16_t age{0};
char gender{'M'};
std::string userName;
};
struct Other {
std::string userName;
std::map<uint32_t, std::string> properties;
};
} // namespace MyLib
请注意,为了良好的风格,我将它们放在命名空间中,这样我们就可以强调 ADL 用于查找 serialize
重载。现在让我们定义重载:
namespace MyLib {
#define SERIALIZER(Aggregate) \
template <typename Archive> \
void serialize(Archive& ar, Aggregate& s, unsigned version) \
{ \
pfr::for_each_field(s, [&](auto&& f) { ar & f; }); \
}
SERIALIZER(Frame)
SERIALIZER(Other)
} // namespace MyLib
使用宏我们避免重复代码。当然你也可以不使用宏来做到这一点。
现在您可以同时序列化两者。假设我们有:
MyLib::Frame const diablo{178, 42, 37, 'F', "Diablo"};
MyLib::Other const other{"diablo", {{1, "one"}, {2, "two"}, {3, "three"},}};
然后序列化为文本流:
boost::archive::text_oarchive oa(ss);
oa & diablo;
oa & other;
已经在包含例如
的流中产生结果
22 serialization::archive 19 0 0 178 42 37 70 6 Diablo 0 0 6 diablo 0 0 3 0 0
0 1 3 one 2 3 two 3 5 three
完整演示
此演示检查反序列化的结果实际上与原始结构相同:
#include <string>
#include <map>
namespace MyLib {
struct Frame {
uint32_t address{0};
uint16_t marks{0};
uint16_t age{0};
char gender{'M'};
std::string userName;
};
struct Other {
std::string userName;
std::map<uint32_t, std::string> properties;
};
} // namespace MyLib
#include <boost/pfr.hpp>
namespace pfr = boost::pfr;
namespace MyLib {
#define SERIALIZER(Aggregate) \
template <typename Archive> \
void serialize(Archive& ar, Aggregate& s, unsigned version) \
{ \
pfr::for_each_field(s, [&](auto&& f) { ar & f; }); \
}
SERIALIZER(Frame)
SERIALIZER(Other)
} // namespace MyLib
#include <iostream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/map.hpp>
int main() {
MyLib::Frame const diablo{178, 42, 37, 'F', "Diablo"};
MyLib::Other const other{"diablo", {{1, "one"}, {2, "two"}, {3, "three"},}};
std::stringstream ss;
{
boost::archive::text_oarchive oa(ss);
oa << diablo;
oa << other;
}
std::cout << ss.str() << "\n";
{
boost::archive::text_iarchive ia(ss);
MyLib::Frame f;
MyLib::Other o;
ia >> f >> o;
std::cout << std::boolalpha;
std::cout << "Frame identical: " << pfr::eq(diablo, f) << "\n";
std::cout << "Other identical: " << pfr::eq(other, o) << "\n";
}
}
版画
g++ -std=c++2a -O2 -Wall -pedantic -pthread main.cpp -lboost_serialization && ./a.out
22 serialization::archive 19 0 0 178 42 37 70 6 Diablo 0 0 6 diablo 0 0 3 0 0 0 1 3 one 2 3 two 3 5 three
Frame identical: true
Other identical: true
我正在尝试使用 boost 将我的结构存储到 txt 文件中,但无法做到。我正在使用提升库。 示例结构
struct Frame
{
uint32_t address{ 0 };
uint16_t marks{ 0 };
uint16_t age{ 0 };
char gender{ 'M' };
std::string userName;
};
对于二进制有简单的代码
boost::archive::binary_oarchive ar(ofs, boost::archive::no_header);
ar << boost::serialization::make_binary_object(&f, sizeof(Frame));
假设文件是用 fstream 对象打开的,'f' 是 'Frame'
的对象我想知道有没有类似的写结构到txt文件的方法,不想一一写数据类型。 假设我们不知道结构内部数据类型的types/number。
正如其他人所评论的那样,您将必须提供序列化助手来告诉 Boost 如何进行成员序列化。
如果你只有这样的聚合,你可以在一定程度上自动生成这个函数 Boost PFR:
pfr::for_each_field(s, [&](auto&& f) { ar & f; });
这是一个例子:
namespace MyLib {
struct Frame {
uint32_t address{0};
uint16_t marks{0};
uint16_t age{0};
char gender{'M'};
std::string userName;
};
struct Other {
std::string userName;
std::map<uint32_t, std::string> properties;
};
} // namespace MyLib
请注意,为了良好的风格,我将它们放在命名空间中,这样我们就可以强调 ADL 用于查找 serialize
重载。现在让我们定义重载:
namespace MyLib {
#define SERIALIZER(Aggregate) \
template <typename Archive> \
void serialize(Archive& ar, Aggregate& s, unsigned version) \
{ \
pfr::for_each_field(s, [&](auto&& f) { ar & f; }); \
}
SERIALIZER(Frame)
SERIALIZER(Other)
} // namespace MyLib
使用宏我们避免重复代码。当然你也可以不使用宏来做到这一点。
现在您可以同时序列化两者。假设我们有:
MyLib::Frame const diablo{178, 42, 37, 'F', "Diablo"};
MyLib::Other const other{"diablo", {{1, "one"}, {2, "two"}, {3, "three"},}};
然后序列化为文本流:
boost::archive::text_oarchive oa(ss);
oa & diablo;
oa & other;
已经在包含例如
的流中产生结果22 serialization::archive 19 0 0 178 42 37 70 6 Diablo 0 0 6 diablo 0 0 3 0 0
0 1 3 one 2 3 two 3 5 three
完整演示
此演示检查反序列化的结果实际上与原始结构相同:
#include <string>
#include <map>
namespace MyLib {
struct Frame {
uint32_t address{0};
uint16_t marks{0};
uint16_t age{0};
char gender{'M'};
std::string userName;
};
struct Other {
std::string userName;
std::map<uint32_t, std::string> properties;
};
} // namespace MyLib
#include <boost/pfr.hpp>
namespace pfr = boost::pfr;
namespace MyLib {
#define SERIALIZER(Aggregate) \
template <typename Archive> \
void serialize(Archive& ar, Aggregate& s, unsigned version) \
{ \
pfr::for_each_field(s, [&](auto&& f) { ar & f; }); \
}
SERIALIZER(Frame)
SERIALIZER(Other)
} // namespace MyLib
#include <iostream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/map.hpp>
int main() {
MyLib::Frame const diablo{178, 42, 37, 'F', "Diablo"};
MyLib::Other const other{"diablo", {{1, "one"}, {2, "two"}, {3, "three"},}};
std::stringstream ss;
{
boost::archive::text_oarchive oa(ss);
oa << diablo;
oa << other;
}
std::cout << ss.str() << "\n";
{
boost::archive::text_iarchive ia(ss);
MyLib::Frame f;
MyLib::Other o;
ia >> f >> o;
std::cout << std::boolalpha;
std::cout << "Frame identical: " << pfr::eq(diablo, f) << "\n";
std::cout << "Other identical: " << pfr::eq(other, o) << "\n";
}
}
版画
g++ -std=c++2a -O2 -Wall -pedantic -pthread main.cpp -lboost_serialization && ./a.out
22 serialization::archive 19 0 0 178 42 37 70 6 Diablo 0 0 6 diablo 0 0 3 0 0 0 1 3 one 2 3 two 3 5 three
Frame identical: true
Other identical: true