c++ - 我需要帮助以连续方式将对象的字段正确写入文件
问题描述
我正在做一个项目,该项目基本上将我创建的一些对象的字段数据的内容写入文件(其中一个是 PERSON 类的 pers1);
我已将数据插入到对象 pers1 的字段成员中,并打开了一个文件,尝试使用 file.write 函数将这些字段成员(字符串名称、姓氏和无符号整数年龄)的内容写入文件。它写了部分内容,中间有很多垃圾。请帮我编写正确的代码,以便我可以将每个人的详细信息连续写入文件。谢谢
#include<iostream>
#include<string>
#include<fstream>
#include <sstream>
#include <iomanip>
#include <list>
class PERSON
{
string name;
string surname;
unsigned int age;
public:
void inputinfo()
{
cin>>name;
cin>>surname;
cin>>age;
}
outputinfo()
{
cout<<name;
cout<<surname;
cout<<age;
}
};
class STUDENT: public PERSON
{
int ID;
float marks_sum;
string belonging_class;
public:
inputinfo()
{
cin>>name;
cin>>surname;
cin>>age;
cin>>ID;
cin>>marks_sum;
cin>>belonging_class;
}
};
void writeinfile()
{
PERSON pers1;
ofstream file1
file1.open("Students.txt", std::ofstream::out | std::ofstream::app);
pers1.inputinfo();
file1.write(pers1.c_str(),pers1.length()); // this is the second aproach I've found on internet, but it gives errors;
file1.write((char*)&pers1, sizeof(pers1)); // this one is puting alot of garbage into the file, alongside fields data.
fisier.close();
}
int main
{
int opt1, opt2;
char option;
switch(opt1)
{
case 1:
do
{
cout<<endl;
<<"Choose one of variants"<<"1.Students"<<"2.Teachers"<<"3.Get back to main menu"<<endl;
cin>>opt2;
switch(opt2)
{
case 1:
do
{
cout<<"Do you wish to introduce a new student(Y/N)?";
cin>>option;
if(option!='N')
writeinfile()
} while(option!='N');
break;
default:
cout<<"Incorect!"<<endl;
}
while(opt2!=3);
break;
case 2: "...."
;
break
case 3: "...."
;
break;
}
}
}
每次调用上述函数时,我都希望将字段数据干净地写入文件中。例如对于第一次迭代,当我在对象的字段中输入数据时:姓名:John,姓:Doe,年龄:45,我希望在文件中看到这些数据(并且中间没有垃圾)。
解决方案
#include <iostream>
#include <fstream>
std::ostream& operator<< (std::ostream& os, const PERSON& value )
{
// here, you decide how the output format should look like. See below.
// ...
return os;
}
std::istream& operator>> (std::istream& is, PERSON& value )
{
// here, you do the reverse of what you chose in operator<<(). See below.
// ...
return is;
}
虽然您将能够快速破解这两个功能的实现,但值得考虑您想要完成的要求:
- 维护?当您更改您的 PERSON(例如额外的字段)时,您的文件将来会发生什么?您还希望能够使用那些旧文件吗?
- 稳健性。您是否必须注意本地化?如果你的第一个中国学生带着汉字名字到达会发生什么?你需要utf8编码还是类似的?你会遇到“缺失值”吗?
- 可扩展性?您最终会用自己的 SQL 编写自己的小数据库,以便稍后查询人员子集吗?一旦文件超出预期,您还能阅读整个文件吗?带有其他数据的新文件是否会到达,以后是否需要关联它们?(外连接,内连接,...)
正如您从这个简短且肯定不完整的列表中看到的那样,您正处于十字路口:改用数据库?使用标准的序列化格式,如 XML 或 JSON 或协议缓冲区或 FastNProto 或当今流行的任何东西?或者只是继续做你自己的事情,因为它无论如何都是一件快速而肮脏的事情?
现在,到实际的事情:
在你的内部operator<<
,你可以像这样“转储”你的元素(坚持你在问题中写的):
os << "name: " << value.name.c_str()
<< ", surname: " << value.surname.c_str()
<< ", age: " << value.age
<< std::endl;
并将其读回,您operator>>
相应地实施。
std::string tag;
is >> tag; // optionally make sure it is "name:"
is >> value.name;
// ... (The commas might need some fiddling... well you wanted help not a full solution...)
然后,您需要做的就是对其进行测试,例如使用字符串流、序列化一个人、将其读入另一个实例并进行比较。你应该完成了;)
推荐阅读
- apache-kafka - Kafka分区索引文件
- java - 创建新数组时使用“char”:int[] a = new int['a']
- c# - 将类型与 EF Core 的隐式运算符一起使用
- batch-file - 这个批处理文件如何结束自己的进程?
- c++ - 'std::wstring_convert' 尽可能多地转换(来自 UTF8 文件读取块)
- wordpress - Wordpress 钩子在调用之前触发,而不是在调用之后触发
- html - 背景图像不时更改时的文本可见性问题
- javascript - 使用水线的model.create/createEach时如何查找未插入/跳过的行
- android - FileProvider:安装 APK。解析包时出错
- python - 如何在 matplotlib 中反转条形图上的刻度顺序?