如何将二进制文件加载/读入“vector <vector <bitset <32 =”“>&gt;”在c ++中?

时间:2017-04-03 08:46:29

标签: c++ vector save ifstream bitset

我在加载/阅读

时遇到问题
vector<vector< bitset<32> > 

(在我的代码中称为/ typedef'ed为人口)

使用以下代码存储的

void genetic_algorithm::save_generation(population pop_to_save, string filename){
  std::ofstream file(filename, std::ofstream::binary);
  unsigned long n;
  for(size_t i = 0; i < pop_to_save.size(); i++ )
  {
    if ( pop_to_save[i].size() > 0 )
    {
      n = pop_to_save[i][0].to_ulong();
      const char* buffer = reinterpret_cast<const char*>(&n);
      file.write(buffer, pop_to_save[i].size());
    }
  }
}

因此我需要的是一个可以加载的函数,即:

population genetic_algorithm::load_generation(string filename){
  // TODO
}

最诚挚的问候,

的Mathias。

修改

我已经自己解决了这个问题(从评论中得到了一些帮助) 以下是可能遇到同样问题的最终代码:

void genetic_algorithm::save_generation(population pop_to_save, string filename){
  std::ofstream file(filename, std::ofstream::binary);
  unsigned long n;
  for(size_t i = 0; i < pop_to_save.size(); i++ ) {
    for (size_t j = 0; j < pop_to_save[i].size(); j++) {
      n = pop_to_save[i][j].to_ulong();
      file.write(reinterpret_cast<const char*>(&n), sizeof(n));
    }
  }

  std::cout << "Saved population to: " << filename << '\n';
}

population genetic_algorithm::load_generation(string filename){
  std::ifstream file(filename, std::ofstream::binary);
  population loaded_pop (20, std::vector<bitset<32>> (394,0));
  unsigned long n;
  for(size_t i = 0; i < 20; i++ ) {
    for (size_t j = 0; j < 394; j++) {
      file.read( reinterpret_cast<char*>(&n), sizeof(n) );
      loaded_pop[i][j] = n;
    }
  }

  std::cout << "Loaded population from: " << filename << '\n';
  return loaded_pop;
}

1 个答案:

答案 0 :(得分:0)

我检查了你的方法genetic_algorithm::save_generation(),这是我发现的:

  • bitset<32>以打包的形式存储32位(可能是一个32位或类似的unsigned int)。

  • vector<bitset<32> >存储此类位集的动态数组。

  • vector<vector<bitset<32> > >存储动态数组的这种动态位组数组。

到目前为止,这么好。在方法genetic_algorithm::save_generation()中,循环遍历外部向量的所有元素以转储每个内部向量的内容(如果不是空的)。

file.write(buffer, pop_to_save[i].size());可能不是你想要的。第二个arg。 std::ostream::write()的是字符数。你传递了res​​p的size()。内部向量返回元素的数量(但不是以字节为单位的大小)。但元素大小(bitset<32>)可能比一个字符大。更好的方法(尽管不是最好的)是使用file.write(buffer, 4 * pop_to_save[i].size());。 (sizeof (char):1,sizeof bitset<32>:希望4,但我会检查一下。)

因此,更安全的是使用file.write(buffer, pop_to_save[i].size() * sizeof pop_to_save[i][0]);。这更好但仍然不完美。如果要在多个平台上使用应用程序,则可能会失败,因为文件格式现在变为平台相关。 (这取决于sizeof pop_to_save[i][0]。)

因此,最好的方法是为内部向量创建一个嵌套循环,并使用一种独立于平台的大小(例如std::uint32_t)单独存储它们的元素。

但是,我的实际问题是设计问题:

如果存储动态数组的动态数组(其中每个内部数组可能是任意大小),那么您还必须存储这些内部数组的元素数。这是我在方法genetic_algorithm::save_generation()中遗漏的内容。

可能是,您的加载问题是由于您必须为要加载的位保留或调整内部向量的大小,但您不知道具有哪个大小。我的回答:你不知道。缺少此信息(并且必须以某种方式提供,例如通过文件本身提供)。