所以基本上我试图在.dat文件中保存一个类,但是在我的代码中,但是它表示此错误没有匹配的成员函数来调用“ open”,但是我放了fstream标头。我不知道我写错了什么。我使用Xcode10。
class memberinformation
{
string name; //name
long int phonenumber; // phone number
int memberid; // member id
public :
memberinformation()
{ name="not assigned" ;
phonenumber=0;
memberid=0;
}
int option3();
int option2();
int option1();
int option4();
};
void wrt_file() //file function
{
memberinformation k;
fstream f;
f.open ("information.dat",ios::app,ios::binary) //this is where I get the error.
f.write((char*)&k,sizeof(k));
}
答案 0 :(得分:3)
您很幸运被一个简单的错误阻止了。 @ Alex44已经显示了如何消除错误:
f.open ("information.dat",ios::app|ios::binary); //this is where I get the error.
但是以下一行甚至更糟:
f.write((char*)&k,sizeof(k));
因为编译器不会显示任何错误,而字符串的内容不会保存在文件中。 std::string
不可复制,因此,memberinformation
类也不是。因此,您不应尝试将其作为原始字节写入文件。
您应该编写一个写入二进制流的序列化函数(只是一种可能的序列化方式):
phonenumber
作为long int(在那里没有问题)memberid
作为一个整数(在那里没有问题)name.size
作为size_t
name.data
为name.size
个字节答案 1 :(得分:2)
另外两个答案已经回答:
我建议您通过使用流运算符的标准C ++技术来序列化对象。这使得编写/读取对象变得很简单,并且通常使调试问题变得容易。
使用@serge-ballesta在他的帖子中建议的格式:
class memberinformation
{
string name; //name
long int phonenumber; // phone number
int memberid; // member id
public :
// OLD STUFF GOES HERE
void swap(memberinformation& other) noexcept
{
using std::swap;
swap(name, other.name);
swap(phonenumber, other.phonenumber);
swap(memberid, other.memberid);
}
friend std::ostream& operator<<(std::ostream& str, memberinformation const& data)
{
return str << data.phonenumber << " "
<< data.memberid << " "
<< data.name.size() << " "
<< data.name << " ";
}
friend std::istream& operator<<(std::istream& str, memberinformation& data)
{
memberinformation tmp;
std::size_t nameSize
if (str >> tmp.phonenumber >> tmp.memberid >> nameSize) {
// All sizes were read correctly.
tmp.name.resize(nameSize);
if (str.ignore(1).read(&tmp.name[0], nameSize)) {
// ignored the space and read the name correctly.
// So now we update the "data" object
tmp.swap(data);
}
}
return str;
}
};
现在输入您的代码:
int main()
{
memberinformation object;
std::cout << object;
std::cin >> object;
std::ofstream file("Data.dat");
file << object;
}
答案 2 :(得分:1)
您错过了分号,并且需要“按位或”标记:
void wrt_file() //file function
{
memberinformation k;
fstream f;
f.open ("information.dat",ios::app|ios::binary); //this is where I get the error.
...
}
答案 3 :(得分:-1)
以上答案解决了您的最初问题。我将再谈两个。
首先,您可能应该在方法末尾使用f.close()。让它脱离作用域并从那里清理可能是完全好的,但是我个人认为这很丑陋,我不会指望它。
第二,除非确实有充分的理由,否则我不会以二进制形式存储数据。它不会是便携式的。上面的Serge建议使用序列化方法。我会考虑另一种方法。我会以人类可读的形式(例如JSON)写入文件。是的,还有很多工作,但是...
-如果您更改班级,仍然可以读取旧文件 -它们可跨环境移植 -您实际上可以查看它们并轻松了解它们包含的内容
因此Serge的上述建议并不可怕,但我会选择更现代的序列化/反序列化样式。
请注意,您的f.write无法使用,因为您的对象包含其他对象,您不知道它们在后台如何工作。例如,该字符串几乎肯定不能以您尝试的方式转储。另外,您不仅要转储数据。
此外,您应该打印f sizeof(k)。您可能会发现有趣的信息。尝试考虑每个字节。您可以打印出sizeof(k.name)来帮助您解决其中的一些问题。
我几乎肯定这样做的信息会让您感到惊讶,但是我自己并没有真正做到这一点,因为我永远不会尝试对C ++对象进行原始内存复制,而这实际上就是您想要做的事情。