Arashdn
Arashdn

Reputation: 731

reading data from files

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

Answers (2)

Ajay
Ajay

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

Cornstalks
Cornstalks

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 CStrings 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

Related Questions