简体   繁体   English

读写矢量 <bool> 到C ++中的文件

[英]Reading and writing vector<bool> to a file in c++

I am having a vector whose size can be really big (1 million elements). 我有一个向量,其大小可能真的很大(一百万个元素)。 I am wrote the contents of the vector to a file as byte values. 我将向量的内容作为字节值写入到文件中。 I am not able to figure out how I can read the byte values back into the vector. 我无法弄清楚如何将字节值读回到向量中。

Here is the code: 这是代码:

#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;
}

[edit] Closed the file after writing and the output is very different from the input. [edit]写入后关闭文件,输出与输入非常不同。

1.0.1.0.1.
SIZE: 6
1.1.1.0.1.1.

How can I get the correct elements into the vector out_ve? 如何将正确的元素放入向量out_ve?

Writing data from most STL containers cannot be done with outfile.write((const char*)&(ve[0]), ve.size()); 从大多数STL容器写入数据无法通过outfile.write((const char*)&(ve[0]), ve.size()); because they manage their memory in complex ways that's fundamental to the way they operate. 因为他们以复杂的方式管理内存,这对于他们的运作方式至关重要。 With vector , it works, because memory storage is contiguous, but vector<bool> is special because of the way it packs multiple bools into a single byte. 使用vector ,它可以工作,因为内存存储是连续的,但是vector<bool>是特殊的,因为它将多个vector<bool>打包到一个字节中。 As commenters have already pointed out, ve[0] returns a special temporary quasi-reference type, and writing that reference out by casting to a char* will produce something totally unrelated to the data that's in the vector. 正如评论者已经指出的那样, ve[0]返回一个特殊的临时准引用类型,并且通过强制转换为char*写出该引用将产生与向量中的数据完全无关的东西。

Even if this construction gave you access to the raw memory of the vector, the code that you're using to write out the data is incompatible with the code that you're using to read in the data. 即使此构造使您可以访问向量的原始存储器,但用于写出数据的代码与用于读入数据的代码也不兼容。 The code that you're using to write out the data would pack 8 bool entries into each char , but the code you're using to read in the data converts each char into a single bool . 您用于写出数据的代码会将 8个bool条目打包到每个char ,但是您用于读取数据的代码会将每个char转换为单个bool

Since you're reading back your data using an istreambuf_iterator , why not write it out the same way: 由于您正在使用istreambuf_iterator回读数据,所以为什么不以相同的方式将其写出:

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

This writes out one bool per byte. 这样每字节写出一个bool

If you want to write out data in a packed representation that writes one bit per bool , I think you'll need to invent your own input and output iterators. 如果您想以打包表示形式写出数据,每个bool写一个位,我认为您需要发明自己的输入和输出迭代器。

vector<bool> is not a real vector . vector<bool>不是真实的vector Code you found elsewhere to work on vectors, won't. 您在其他地方找到的可用于向量的代码不会。 And you must not ignore the "address of a temporary". 并且您一定不能忽略“临时地址”。 This line 这条线

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

will not work on vector<bool> . 不适用于vector<bool>

The issue is that the thing you're taking the address of isn't the type you think it is. 问题在于您要处理的地址不是您认为的类型。

try this for the AND opperation: 尝试执行AND操作:

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

you should look into operator overloading and make an operator that returns the next unsigned char within the file then use atoi to convert the value to an integer 您应该研究运算符重载,并使运算符返回文件中的下一个无符号字符,然后使用atoi将值转换为整数

Ex. 防爆。

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

the above is just an example (not tested. haven't use c++ templates in a while so it may need reworking 以上仅是一个示例(未经测试。一段时间未使用c ++模板,因此可能需要重新制作)

best of luck, 祝你好运

Alexander Frankland (Tandex) 亚历山大·弗兰克兰(Tandex)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM