Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:从二进制文件读取输入时出现问题_C++_Class_Binaryfiles - Fatal编程技术网

C++ C++;:从二进制文件读取输入时出现问题

C++ C++;:从二进制文件读取输入时出现问题,c++,class,binaryfiles,C++,Class,Binaryfiles,我在AccountManagement.cpp有一个AccountManagement班。我在Account.cpp中有另一个名为Account的类。我有一个模板,它使用OrderList类对列表中的给定数据进行排序,OrderList类也有自己的迭代器。AccountManagement类以二进制文件的形式输出帐户列表,如下所示: void AccountManagement::saveData(const char * file) //saves data in the specified

我在AccountManagement.cpp有一个AccountManagement班。我在Account.cpp中有另一个名为Account的类。我有一个模板,它使用OrderList类对列表中的给定数据进行排序,OrderList类也有自己的迭代器。AccountManagement类以二进制文件的形式输出帐户列表,如下所示:

void AccountManagement::saveData(const char * file) //saves data in the specified binary file
{
    ofstream out(file, ios::out | ios::binary);
    if(!out)
    {
        cerr<<"Problem opening output file!"<<endl;
    }   
    OrderedList<Account>::iterator it = this->account_manager.begin();
    for(int i = 0; i < this->total_accounts; i++)
    {
        Account temp = *it;
        out.write((char*)&temp, sizeof(Account));
        it++;
    }
    out.close();
}
void AccountManagement::saveData(const char*file)//将数据保存在指定的二进制文件中
{
流输出(文件,ios::out | ios::binary);
如果(!out)
{

cerr我不知道
MYLIB::Date
类,但是在那里有一个
std::string
对象就足够了

std::string
对象动态分配内存以适应其包含的字符串。而堆上分配的内存仅对当前进程可用,您不能保存指针(位于
std::string
类中)并从其他进程加载它,希望该指针处有有效内存

如果您在一个进程中保存指向动态分配内存的指针,并从另一个进程加载和使用它,那么您将具有未定义的行为

您需要保存该字符串。也可能是
MYLIB::Data
对象



免责声明:它将在具有单一统一地址映射的小型嵌入式系统上工作,不幸的是,所有面向用户的操作系统(如Windows、OSX和Linux)在进程之间有单独的地址空间和墙。

我不知道
MYLIB::Date
类,但是在其中有
std::string
对象就足够了

std::string
对象动态分配内存以适应其包含的字符串。而堆上分配的内存仅对当前进程可用,您不能保存指针(位于
std::string
类中)并从其他进程加载它,希望该指针处有有效内存

如果您在一个进程中保存指向动态分配内存的指针,并从另一个进程加载和使用它,那么您将具有未定义的行为

您需要保存该字符串。也可能是
MYLIB::Data
对象



免责声明:它将在具有单一统一地址映射的小型嵌入式系统上工作,不幸的是,所有面向用户的操作系统(如Windows、OSX和Linux)在进程之间有单独的地址空间和墙。

我不知道
MYLIB::Date
类,但是在其中有
std::string
对象就足够了

std::string
对象动态分配内存以适应其包含的字符串。而堆上分配的内存仅对当前进程可用,您不能保存指针(位于
std::string
类中)并从其他进程加载它,希望该指针处有有效内存

如果您在一个进程中保存指向动态分配内存的指针,并从另一个进程加载和使用它,那么您将具有未定义的行为

您需要保存该字符串。也可能是
MYLIB::Data
对象



免责声明:它将在具有单一统一地址映射的小型嵌入式系统上工作,不幸的是,所有面向用户的操作系统(如Windows、OSX和Linux)在进程之间有单独的地址空间和墙。

我不知道
MYLIB::Date
类,但是在其中有
std::string
对象就足够了

std::string
对象动态分配内存以适应其包含的字符串。而堆上分配的内存仅对当前进程可用,您不能保存指针(位于
std::string
类中)并从其他进程加载它,希望该指针处有有效内存

如果您在一个进程中保存指向动态分配内存的指针,并从另一个进程加载和使用它,那么您将具有未定义的行为

您需要保存该字符串。也可能是
MYLIB::Data
对象



免责声明:它适用于具有单一统一地址映射的小型嵌入式系统,不幸的是,所有面向用户的操作系统(如Windows、OSX和Linux)在进程之间都有单独的地址空间和墙。

您的函数
AccountManagement::output()
给人的印象是,如果保存对象并将其再次加载到同一个对象中,同时字符串没有更改,则它可以完美地工作

怎么了?

一旦您的对象不再是POD对象(即,它包含使用指针或使用虚拟函数等的数据),您就不能仅仅通过将其内存写入磁盘来保存它

在您的例子中,第二个函数由于这个原因失败。第一个函数只是给人一种工作的印象。字符串是一个复杂的对象,它在某处存储指向动态分配内存的指针。如果您像以前那样写入对象并将其读回,而不更改对象,那么内存中的值将被简单地重新读取。读取的隐藏指针的值与读取之前的值完全相同。这是一个非常幸运的情况。但在大多数情况下,它会失败

如何解决它?

要保存对象,应将其序列化:使用适当的函数将每个组件分别写入/读取到文件中


要做到这一点,最简单的方法是使用一些现有的序列化库,例如

您的函数
AccountManagement::output()
void AccountManagement::output()
{
    ifstream in("accounts.dat", ios::in | ios::binary);
    if(!in)
    {
        cerr<<"File doesn't exist!"<<endl;
        exit(1);
    }
    Account acc;
    while(in.read((char*)&acc, sizeof(Account)))
    {
        cout<<acc;
    }
    in.close();
}
void loadData()
{
    ifstream in("accounts.dat", ios::in | ios::binary);
    if(!in)
    {
        cerr<<"File doesn't exist!"<<endl;
        exit(1);
    }

    Account acc;
    while(in.read((char*)&acc, sizeof(Account)))
    {
        cout<<acc;
    }
    in.close();
}
class Account 
{
    friend ostream& operator<<(ostream&,const Account&); //overloading << operator
    friend istream& operator>>(istream&,Account&); //overloading >> operator
    public:
        void operator=(const Account&); //overloading = operator
        bool operator<=(const Account&); //overloading <= operator
        bool operator<(const Account&); //overloading < operator

    private:
        string number; //Account Number
        char name[100]; //Account holder's name
        char sex; //M or F indicating the gender of account holder
        MYLIB::Date dob; //date of birth of account holder
        char address[100]; //address of account holder
        char balance[20]; //balance of account holder
};