0

ファイルにデータを保存する必要がある 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.

私に何ができる?

4

2 に答える 2

2

気をつけろ。という名前Client myClient(); の関数を宣言しますmyClient。関数のアドレスに書き込むと、クラッシュなどの問題が発生します。に変更するだけClient myClient;です(実際のオブジェクトを作成してから、実際Clientにオブジェクトに書き込む方法です)。もちろん、Clientそのようなオブジェクトへの書き込みが安全であることを願っています (たとえば、ポインターに関する Joachim Pileborg のコメントを参照してください)。

たとえば、次のコードを見てください。

#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;
}

結果(g++ を使用) が出力されます。

F1SvE
1S

重要な点は、それらが同じではないということです! パラメータをとらず、 を返すs1という名前の関数の宣言です。実物です。これは、C++ の「最も厄介な解析」として知られています (多くのフラストレーションを引き起こす可能性があるため)。s1Ss2S

編集:ああ、あなたは質問をより多くの(実際の)コードで更新し続け、それは物事を変え続けます。今後の参考のために、完全な実際のコードから始めてください。そうすれば、人々は物事を変更し続ける必要がなくなります :)

そのような sを安全に書くことはできませんCString。それらはポインターを内部に保存し、Joachim Pileborg が言及しているように、それらを読み込もうとすると大混乱を引き起こします。

さらに、Clientデフォルトのコンストラクターがなくなりました (独自のコンストラクターを提供したため)。だから、あなたもClient myClient;もう言うことはできません。適切なコンストラクターを使用する必要があります。

于 2013-01-19T15:54:07.587 に答える
0

CString の内容をバイナリ データとして格納することはできません。fprintfデータを書き込むには、CStdioFile::WriteStringまたは同様のものを使用する必要があります。CString には定数サイズのバッファーがないため、アドレスオブは無効になります。

学習の問題を部分に分割することをお勧めします-練習CString、ファイルIO、クラス設計、およびUIをさまざまな側面として。他の側面に慣れない限り、それらすべてを混ぜないでください。何が問題だったのかわからないでしょう。

また、明らかなエラーとして投稿したコード:createメソッドにはクラスにパラメーターがありませんが、実装中にパラメーターがあります!

于 2013-01-20T04:41:54.537 に答える