0

サイズが非常に大きくなる可能性のあるベクトル(100万要素)があります。ベクトルの内容をバイト値としてファイルに書き込みます。バイト値をベクトルに読み戻す方法がわかりません。

コードは次のとおりです。

#include <fstream>
#include <vector>
#include <iterator>
#include <iostream>
using namespace std;

int main()
{
  // Filling a vector with values
  std::vector<bool> ve;
  ve.push_back(true);
  ve.push_back(false);
  ve.push_back(true);
  ve.push_back(false);
  ve.push_back(true);
  // Printing the values of the vector
  for(unsigned int i = 0; i < ve.size(); i++)
      cout << ve.at(i) << ".";
  cout << endl;

  // Writing the vector contents to a file
  const char* file_name = "abc.txt";
  ofstream outfile(file_name, ios::out | ios::binary);
  outfile.write((const char*)&(ve[0]), ve.size());
  outfile.close();
  // Reading the file and filling the vector with values
  ifstream infile ("abc.txt", ifstream::binary);
  vector<bool> out_ve((std::istreambuf_iterator<char>(infile)),
                       std::istreambuf_iterator<char>());

  while( !infile.eof() )
      out_ve.push_back(infile.get());

  // Checking if the values read are the same as the original values
  cout << "SIZE: " << out_ve.size() << endl;
  for(unsigned int i = 0; i < out_ve.size(); i++)
    cout << out_ve.at(i) << ".";
  cout << endl;

  infile.close();
  return 0;
}

[編集]書き込み後にファイルを閉じましたが、出力が入力と大きく異なります。

1.0.1.0.1.
SIZE: 6
1.1.1.0.1.1.

どうすれば正しい要素をベクトルout_veに入れることができますか?

4

3 に答える 3

7

outfile.write((const char*)&(ve[0]), ve.size());ほとんどのSTLコンテナからのデータの書き込みは、操作方法の基本である複雑な方法でメモリを管理するため、使用できません。を使用vectorすると、メモリストレージが連続しているためvector<bool>機能しますが、複数のブールを1バイトにパックする方法のために特別です。コメント投稿者がすでに指摘しているようにve[0]、特別な一時的な準参照型を返し、にキャストしてその参照を書き出すとchar*、ベクトル内のデータとはまったく関係のないものが生成されます。

この構造により、ベクトルの生のメモリにアクセスできたとしても、データの書き込みに使用しているコードは、データの読み取りに使用しているコードと互換性がありません。データの書き込みに使用しているコードは、それぞれに8つのエントリをパックしますが、データの読み込みに使用しているコードは、それぞれを1つに変換します。boolcharcharbool

を使用してデータを読み戻しているistreambuf_iteratorので、同じ方法でデータを書き出してみませんか。

std::copy(ve.begin(), ve.end(), std::ostreambuf_iterator<char>(outfile));

これによりbool、バイトごとに1つが書き込まれます。

ごとに1ビットを書き込むパック表現でデータを書き出す場合はbool、独自の入力および出力イテレータを考案する必要があると思います。

于 2012-07-04T01:31:04.490 に答える
1

vector<bool>本物ではありませんvector。ベクトルを処理するために他の場所で見つけたコードは、機能しません。また、「一時的なアドレス」を無視してはなりません。この行

outfile.write((const char*)&(ve[0]), ve.size());

では動作しませんvector<bool>

問題は、あなたがアドレスを取っているものがあなたが思っているタイプではないということです。

于 2012-07-04T01:24:51.137 に答える
-2

AND操作のためにこれを試してください:

#define logical_and(x, y)   ((x==y) ? x | y)

演算子のオーバーロードを調べて、ファイル内の次のunsigned charを返す演算子を作成し、atoiを使用して値を整数に変換する必要があります

元。

template<typename T>
  T operator << (ifstream& file)
  {
    return reinterpret_cast<T>(file.get());
  };

上記は単なる例です(テストされていません。しばらくの間c ++テンプレートを使用していないため、やり直しが必要になる場合があります

幸運を祈ります、

アレクサンダーフランクランド(タンデックス)

于 2012-07-04T01:08:47.590 に答える