c++ - 如何在不使用任何特殊头文件的情况下序列化可能包含 C++ 中用户定义类的其他对象的对象?
问题描述
我正在制作一个包含用户定义类的小程序,该类包含结构类型日期和时间的对象对象。结构日期包含一个字符串类型。我如何序列化包含对象条目以便能够将条目对象存储在文件中以及在 C++ 中读取它?这是我的最小代码:
#include<iostream>
#include<fstream>
#include<string>
#define s ' ' //defining space character
using namespace std;
struct date{
int day;
string month;
int year;
};
struct time{
int hr;
int min;
};
class entry{
private:
date d;
time t;
int sno=0;
public:
void incrementsno(){++sno;}
void getdate(){ //This function gets date
cout<<"\nEnter the date : ";
cout<<"\nDay : ";
cin>>d.day;
cout<<"Month : ";
cin>>d.month;
cout<<"Year :";
cin>>d.year;
}
void gettime(){ //This function gets time
cout<<"\n\nEnter time : ";
cout<<"\nHours :";
cin>>t.hr;
cout<<"Minutes :";
cin>>t.min;
}
};
int main(){
//declaring variables
char c;
string filename;
entry e;
ifstream filer;
ofstream filew;
//getting file name begins
cout<<"Enter the name of file you want to create : ";
cin>>filename;
cout<<"\nThe file name is : "<<filename<<endl;
//getting file name over
//creating and opening file
filew.open(filename.c_str(),ios::binary|ios::out|ios::app);
//file association operation successful
cout<<"\nDo you want to write to file? : ";
cin>>c;
if(c=='y')//Entering date and time
{
do{
e.getdate();
e.gettime();
filew.write((char*)&e,sizeof(e));
cout<<"\nFile write operation successful.\n";
e.incrementsno();
cout<<"\nDo you wish to continue? :";
cin>>c;
}
while(c=='y');
}
else
cout<<"\nReading file...\n";
filew.close();
filer.open(filename.c_str(),ios::binary|ios::in); //opening file for reading
while(filer.read((char*)&e,sizeof(e)))
{
e.showdate();
e.showtime();
}
cout<<"\n\nFile IO successful...";
filer.close();
return 0;
}
解决方案
这是一个基于评论的非工作、半度量流框架。它不起作用 - 这是可以使用的东西。
#include <iostream>
#include <string>
#include <vector>
//-----------------------------------------------------------------------------
struct Date {
int day;
std::string month;
int year;
};
// Date serializing support:
// stream out a Date to a generic stream (like a file)
std::ostream& operator<<(std::ostream& os, const Date& d) {
return os << d.day << '\n' << d.month << '\n' << d.year << '\n';
}
// read a Date from a generic stream (like a file)
std::istream& operator>>(std::istream& is, Date& d) {
return is >> d.day >> d.month >> d.year;
}
// Date adapters for human interaction - only holds references to "real" objects
struct DateUIout {
explicit DateUIout(const Date& d) : date(d) {}
// DateUIout(const Date&) = delete; // not copyable - but made it explicitly
// clear
// holds a reference to the Date struct we'd like to work with
// and an output stream for asking the user questions if needed
const Date& date;
};
std::ostream& operator<<(std::ostream& os, const DateUIout& dui) {
const Date& d = dui.date; // alias to the Date we'd like to work with
return os << "Day: " << d.day << " Month: " << d.month << " Year: " << d.year
<< '\n';
}
struct DateUIin {
explicit DateUIin(Date& d, std::ostream& qs = std::cout) :
date(d), questions(qs) {}
DateUIin(const Date&) = delete; // not copyable - but made it explicitly clear
Date& date;
std::ostream& questions; // used for printing questions to humans
};
std::istream& operator>>(std::istream& is, DateUIin& dui) {
Date& d = dui.date; // alias to the Date we'd like to work with
dui.questions << "Enter the date:\n"
<< " Day: ";
is >> d.day;
dui.questions << " Month: ";
is >> d.month;
dui.questions << " Year: ";
return is >> d.year;
}
//-----------------------------------------------------------------------------
struct Time {
int hr;
int min;
};
// Time serializing support: (much like everything in Date)
// stream out a Time
std::ostream& operator<<(std::ostream& os, const Time& t) {
return os << t.hr << '\n' << t.min << '\n';
}
// read a Time from a stream
std::istream& operator>>(std::istream& is, Time& t) {
return is >> t.hr >> t.min;
}
// Time adapter for human interaction - only holds references to "real" objects
struct TimeUI {
explicit TimeUI(Time& t, std::ostream& qs = std::cout) : tim(t), questions(qs) {}
Time& tim;
std::ostream& questions;
};
std::ostream& operator<<(std::ostream& os, const TimeUI& tui) {
Time& t = tui.tim;
return os << "Hour: " << t.hr << ' ' << t.min << '\n';
}
std::istream& operator>>(std::istream& is, TimeUI& tui) {
Time& t = tui.tim;
tui.questions << "Enter the time:\n Hour: ";
is >> t.hr;
tui.questions << " Minute: ";
return is >> t.min;
}
//-----------------------------------------------------------------------------
struct Timestamp {
Date date{};
Time time{};
};
// Timestamp serializing support:
// stream out a Timestamp
std::ostream& operator<<(std::ostream& os, const Timestamp& ts) {
return os << ts.date << ts.time;
}
// read a Timestamp from a stream
std::istream& operator>>(std::istream& is, Timestamp& ts) {
return is >> ts.date >> ts.time;
}
// Timestamp adapter for human interaction - only holds references to "real" objects
struct TimestampUIout {
TimestampUIout(const Timestamp& Ts) : ts(Ts) {}
// TimestampUIout(const TimestampUI&) = delete;
Timestamp& ts;
};
std::ostream& operator<<(std::ostream& os, const TimestampUIout& tsui) {
return os << DateUIout(tsui.ts.date) << TimeUI(tsui.ts.time, os);
}
struct TimestampUIin {
TimestampUI(Timestamp& Ts, std::ostream& qs = std::cout) :
ts(Ts), questions(qs) {}
TimestampUI(const TimestampUI&) = delete;
Timestamp& ts;
std::ostream& questions;
};
std::istream& operator>>(std::istream& is, TimestampUIin& tsui) {
DateUIin dui(tsui.ts.date, tsui.questions);
TimeUI tui(tsui.ts.time, tsui.questions);
return is >> dui >> tui;
}
//-----------------------------------------------------------------------------
int main() {
Timestamp tmp;
TimestampUI tsui(tmp, std::cout); // bind UI adapter to the Timestamp
std::vector<Timestamp> timestamps;
while(std::cin >> tsui) { // use UI adapter
timestamps.push_back(tmp); // store a raw Timestamp
}
// print collected timestamps - using adapter
for(const Timestamp& ts : timestamps) {
std::cout << TimestampUIout(ts);
}
// print collected timestamps - as they would be streamed to a file
for(const Timestamp& ts : timestamps) {
std::cout << ts;
}
}
推荐阅读
- database - 为什么我的 PLSQL 代码不使用 while 循环进行循环?
- c# - C#:等待 TransformBlock.Completion 挂起而没有响应
- mysql - MySQL插入/更新期间2+并发请求冲突
- python - Selenium 花费太多时间来下载文件
- angular - 无法将故事书添加到 Nrwl Nx 角度应用程序
- php - foreach 子数组中的值求和
- python - 交叉验证估计器的参数无效。值错误
- java - 如何在 JAVA EE JPA 中使用购物车项目保持订单,订单包含多个项目
- angular - 用于多个下拉菜单的 Angular AsyncPipe 加载一次
- swift - SCNNode 不透明度和可见性