从文件中读取数据

时间:2013-01-19 15:05:28

标签: c++ visual-c++ mfc

我正在研究一个需要将数据存储在文件中的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.

我该怎么办?

2 个答案:

答案 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的函数的声明,它不接受任何参数并返回s1S是一个实际的s2对象。这被称为C ++的“最令人烦恼的解析”(因为它会引起很多挫折)。

编辑:哦,小伙子,你不断用更多(实际)代码更新你的问题,并且不断改变。为了将来参考,只需从完整的实际代码开始,这样人们就不必继续改变:)

你不能安全地写S这样的。他们在内部存储指针,就像Joachim Pileborg提到的那样,在试图读取它们时会破坏。

此外,CString不再有默认构造函数(因为您已经提供了自己的构造函数)。所以你不能再说Client了。你必须使用正确的构造函数。

答案 1 :(得分:0)

您不能将CString内容存储为二进制数据。您必须使用fprintfCStdioFile::WriteString或类似的东西来编写数据。 CString没有常量大小的缓冲区,因此地址将无效。

我的建议是将学习问题分解为部分 - 将CString,file-io,类设计和UI作为不同方面进行练习。除非你对其他方面感到满意,否则不要将它们全部混合在一起。你不会知道问题是什么。

此外,您发布的代码显然是错误的:create方法在类中没有任何参数,但在实现时您有一个参数!