如何从保存文件加载对象数据?

时间:2013-06-16 23:12:57

标签: c++ arrays object fstream allocator

我正在开发一个处理创建两个字符串,用户名和密码的项目。这两个元素构成了帐户的对象。在主要的,有一个帐户数组,初始化为10。 我有一个Save&退出选项,将用户名保存在一行,密码保存在同一文件中的下一行。一对线表示另一个帐户。

我的问题是,如何正确保存帐户数据中的数据,然后加载上一个帐户数据中的数据?

每次尝试std::bad_alloc memory函数时都会出现loadAccounts()错误。我有几种不同的方法,但无济于事。

到目前为止,我已经提出了这个来保存数组(到目前为止的工作方式):

void saveAccounts(Account accs [], int numIndexes)
{
std::ofstream savefile("savedata.sav", std::ofstream::binary); // By re-initializing the file, the old contents are overwritten.
for (int i = 0; i < numIndexes; i++)
{
    savefile << accs[i].getUsername() << endl;
    savefile << accs[i].getPassword() << endl;
}
savefile.close();
}

至于我的加载功能,我有:

Account* loadAccounts() // Load the data from the file to later print to make sure it works correctly.
{
cout << "LOADING ACCOUNTS!" << endl;
std::ifstream loadfile("savedata.sav", std::ifstream::binary);

Account * acc_arr; // The "Array" to be returned.
Account tmp_arr [10]; // The array to help the returned "Array."
acc_arr = tmp_arr; // Allowing the "Array" to be used and returned because of the actual array.
if (loadfile.is_open())
{
    int i = 0;
    while (loadfile.good())
    {
        cout << "Loadfile is good and creating Account " << i+1 << "." << endl; // For my own benefit to make sure the data being read is good and actually entering the loop.
        std::string user;
        std::getline(loadfile, user);
        std::string pass;
        std::getline(loadfile, pass);
        Account tmpAcc(user, pass);
        tmp_arr[i] = tmpAcc;
        ++i;
    }
    Account endAcc = Account(); // The default constructor sets Username to "NULL."
    tmp_arr[i] = endAcc;
}
loadfile.close();
cout << "ACCOUNTS LOADED SUCCESSFUL!" << endl;
return acc_arr;
}

我已经收集到我可以通过使用指针和实际数组来返回一个数组,因为实际上不能返回数组。

我尝试在这里使用返回的数组,我试图在加载的数组上“复制”到实际打印的数组。稍后,我将打印数组(acc_arr)以确保已成功加载已加载的数组:

else if (selection == 'l' || selection == 'L')
{
Account * tmp_acc_arr = new Account [10];
    tmp_acc_arr = loadAccounts();
    _getch();
    for (size_t i = 0; i < size_t(10); i++)
    {
        if (tmp_acc_arr[i].getUsername() == "NULL")
        {
            break;
        }
        acc_arr[i] = tmp_acc_arr[i];
        cout << "Added Account " << i << " succesfully." << endl;
    }
}

错误是由最后一段代码引起的。我已经检查过确保使用

正确复制数据

编辑:尴尬......通过使用if语句确保tmp_acc_arr中的数据在主要文件中返回并初始化后确实存储了数据。

2 个答案:

答案 0 :(得分:0)

tmp_arr位于loadAccounts和堆栈中。一旦loadAccounts()返回,它将无效。您的返回值是无效的堆栈指针。

您可以将指针tmp_acc_arr作为参数传递给函数,并使用文件中的值填充它。 您还应检查溢出或更好地使用STL容器,如std :: vector。

修改


void loadAccounts(Account * acc_memory, std::allocator<Account> alloc, size_t acc_array_size) // Load the data from the file to later print to make sure it works correctly.
{
  Account *end_of_construction = acc_memory;
  try
  {
    cout << "LOADING ACCOUNTS!" << endl;
    std::ifstream loadfile("savedata.sav", std::ifstream::binary);
    if (loadfile.is_open() && loadfile.good())
    {
        size_t i = 0;
        for (size_t i=0; i<acc_array_size; ++i)
        {
          if (loadfile.good())
          {
            cout << "Loadfile is good and creating Account " << i+1 << "." << endl; // For my own benefit to make sure the data being read is good and actually entering the loop.
            std::string user, pass;
            std::getline(loadfile, user);
            if (loadfile.good())
            {
              std::getline(loadfile, pass);
              alloc.construct(end_of_construction++, user, pass);
            }
            else alloc.construct(end_of_construction++);
          }
          else alloc.construct(end_of_construction++);
        }
    }
    loadfile.close();
    cout << "ACCOUNTS LOADED SUCCESSFUL!" << endl;
  }
  catch (...)
  {
    size_t num_constructed = end_of_construction-acc_memory;
    for (size_t i=0; i<num_constructed; ++i) alloc.destroy(acc_memory + i);
    throw;
  }
}

一样使用
  size_t const num_elements = 10;
  std::allocator<Account> acc_alloc;
  Account * tmp_acc_arr = acc_alloc.allocate(num_elements);
  loadAccounts(tmp_acc_arr, acc_alloc, num_elements);
  // do stuff
  for (size_t i=0; i<num_elements; ++i) acc_alloc.destroy(tmp_acc_arr + i);
  acc_alloc.deallocate(tmp_acc_arr, num_elements);

答案 1 :(得分:0)

返回指向退出函数后立即销毁的数组的指针。使用该指针会导致未定义的行为,即BAD。

正如您所观察到的,数组不是有效的返回类型,因此要实际返回它,您应将其放在结构中,并返回结构。