我需要帮助以连续的方式将对象的字段正确写入文件
I need help to properly write the fields of an object into a file in a consecutive manner
我正在做一个项目,该项目基本上将我创建的一些对象字段数据的内容写入文件(其中一个是 class 人的 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;
}
虽然您将能够快速破解这 2 个函数的实现,但值得考虑您想要完成的任务的要求:
- 维护?当你改变你的人(例如额外的字段)时,你的文件将来会发生什么?您还想使用那些旧文件吗?
- 稳健性。您需要注意本地化吗?如果您的第一个中国学生的名字是汉字,会发生什么?你需要utf8编码还是类似的?你会遇到"missing values"吗?
- 可扩展性?您最终会用自己的 SQL 编写自己的小型数据库,以便稍后查询人员子集吗?一旦超出预期,您是否仍然能够阅读整个文件?带有其他数据的新文件是否会到达并且稍后需要将它们关联起来? (外连接、内连接、...)
从这个简短但肯定不完整的列表中可以看出,您正处于十字路口:改用数据库?使用标准序列化格式,如 XML 或 JSON 或协议缓冲区或 FastNProto 或当今流行的任何格式?或者只是继续做你自己的事情,因为无论如何这都是一件快速而肮脏的事情?
现在,进入实际的东西:
在你的 operator<<
中,你可以 "dump" 这样的元素(坚持你在问题中写的内容):
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...)
然后,您需要做的就是测试它,例如使用字符串流,序列化一个人,将其读入另一个实例并进行比较。你应该完成了 ;)
我正在做一个项目,该项目基本上将我创建的一些对象字段数据的内容写入文件(其中一个是 class 人的 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;
}
虽然您将能够快速破解这 2 个函数的实现,但值得考虑您想要完成的任务的要求:
- 维护?当你改变你的人(例如额外的字段)时,你的文件将来会发生什么?您还想使用那些旧文件吗?
- 稳健性。您需要注意本地化吗?如果您的第一个中国学生的名字是汉字,会发生什么?你需要utf8编码还是类似的?你会遇到"missing values"吗?
- 可扩展性?您最终会用自己的 SQL 编写自己的小型数据库,以便稍后查询人员子集吗?一旦超出预期,您是否仍然能够阅读整个文件?带有其他数据的新文件是否会到达并且稍后需要将它们关联起来? (外连接、内连接、...)
从这个简短但肯定不完整的列表中可以看出,您正处于十字路口:改用数据库?使用标准序列化格式,如 XML 或 JSON 或协议缓冲区或 FastNProto 或当今流行的任何格式?或者只是继续做你自己的事情,因为无论如何这都是一件快速而肮脏的事情?
现在,进入实际的东西:
在你的 operator<<
中,你可以 "dump" 这样的元素(坚持你在问题中写的内容):
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...)
然后,您需要做的就是测试它,例如使用字符串流,序列化一个人,将其读入另一个实例并进行比较。你应该完成了 ;)