我正在研究一个需要将数据存储在文件中的MFC应用程序
我有一个这样的课程
class Client
{
public:
Client(CString Name , CString LastName , CString Id );
int create();
int update(Client & myClient);
CString name;
CString lastName;
CString id;
};
Client::Client(CString Name , CString LastName , CString Id )
{
name = Name;
lastName=LastName;
id=Id;
}
void displayMessage(CString message , CString title=L"Meesage")
{
MessageBox(NULL,message,title,MB_OK | MB_ICONERROR);
}
int Client::create(Client myClient)
{
ofstream output;
output.open("test.dat" , ios::binary );
if( output.fail() )
{
CString mess;
mess = strerror( errno );
displayMessage(mess);
return 1 ;//anything but 0
}
output.write( (char *) &myClient , sizeof(Client));
output.close();
return 0;
}
int Client::update(Client & myClient)
//also tried passing by value : int update(Client myClient)
{
ifstream input;
input.open("test.dat" , ios::binary );
if( input.fail() )
{
CString mess;
mess = strerror( errno );
displayMessage(mess);
return 1 ;//anything but 0
}
input.read( (char *) &myClient , sizeof(Client));
input.close();
return 0;
}
创建功能效果很好,
但是,关于更新功能我有一些问题
我使用这样的函数:
Client myClient();
myClient.update(myClient);
但是当我运行此功能时出现此错误
Unhandled exception at 0x5adfab2a (mfc100ud.dll) in MyProject.exe: 0xC0000005: Access violation writing location 0x039708fc.
我该怎么办?
答案 0 :(得分:2)
小心。名为Client myClient();
的{{1}} declares a function。写入函数的地址会导致一些问题,比如崩溃。只需将其更改为myClient
(这样您就可以创建一个实际的Client myClient;
对象,然后实际写入一个对象)。当然,我希望写一个这样的Client
对象是安全的(例如,参见Joachim Pileborg关于指针的评论)。
例如,请查看以下代码:
Client
The results(使用g ++)打印出来:
#include <typeinfo> #include <iostream> struct S {}; int main() { S s1(); S s2; std::cout << typeid(s1).name() << std::endl; std::cout << typeid(s2).name() << std::endl; }
F1SvE
重要的是它们不一样! 1S
是名为s1
的函数的声明,它不接受任何参数并返回s1
。 S
是一个实际的s2
对象。这被称为C ++的“最令人烦恼的解析”(因为它会引起很多挫折)。
编辑:哦,小伙子,你不断用更多(实际)代码更新你的问题,并且不断改变。为了将来参考,只需从完整的实际代码开始,这样人们就不必继续改变:)
你不能安全地写S
这样的。他们在内部存储指针,就像Joachim Pileborg提到的那样,在试图读取它们时会破坏。
此外,CString
不再有默认构造函数(因为您已经提供了自己的构造函数)。所以你不能再说Client
了。你必须使用正确的构造函数。
答案 1 :(得分:0)
您不能将CString内容存储为二进制数据。您必须使用fprintf
,CStdioFile::WriteString
或类似的东西来编写数据。 CString没有常量大小的缓冲区,因此地址将无效。
我的建议是将学习问题分解为部分 - 将CString
,file-io,类设计和UI作为不同方面进行练习。除非你对其他方面感到满意,否则不要将它们全部混合在一起。你不会知道问题是什么。
此外,您发布的代码显然是错误的:create
方法在类中没有任何参数,但在实现时您有一个参数!