Reputation: 731
I am working on a MFC application witch needs to store data on a file
I have a class like this
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;
}
Create function works well ,
But , about update function I have some problems
I use function like this:
Client myClient();
myClient.update(myClient);
But I got this error when I run this function
Unhandled exception at 0x5adfab2a (mfc100ud.dll) in MyProject.exe: 0xC0000005: Access violation writing location 0x039708fc.
What Can I do?
Upvotes: 0
Views: 196
Reputation: 18431
You cannot store CString contents as a binary data. You must use fprintf
, CStdioFile::WriteString
or similar thing to write data. CString doesn't have constant-size buffer, and hence the address-of would be invalid.
My suggestion it to break the learning problem into parts - practice CString
, file-io, class design and the UI as different aspects. Don't mix them all, unless you get comfortable with other aspect. You'll not know what the problem was.
Also, the code you posted as obvious error: create
method doesn't have any parameter in class, but while implementing you have a parameter!
Upvotes: 0
Reputation: 38218
Careful. Client myClient();
declares a function named myClient
. Writing to an address of a function is going to cause some issues, like crashing. Just change it to Client myClient;
(that way you're creating an actual Client
object, and then actually writing to an object). Of course, I hope writing to a Client
object like that is safe (see Joachim Pileborg's comment about pointers, for example).
For example, look at the following code:
#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;
}
The results (using g++) print out:
F1SvE
1S
The important point is that they are not the same! s1
is a declaration of a function named s1
that takes no parameters and returns an S
. s2
is an actual S
object. This is known as C++'s "most vexing parse" (because it can cause a lot of frustration).
Edit: Oh boy, you keep updating your question with more (actual) code, and that keeps changing things. For future reference, just start with the complete actual code so people don't have to keep changing things :)
You can't safely write CString
s like that. They store pointers internally, and like Joachim Pileborg mentions, that'll wreck havoc when trying to read them in.
Additionally, Client
has no default constructor anymore (because you've provided your own constructor). So you can't say Client myClient;
anymore either. You'll have to use the right constructor.
Upvotes: 2