从std :: vector <bool> </bool>获取字节

时间:2009-02-15 21:02:26

标签: c++ stl

我有类似下面的内容,在用任意数量的位填充之后,我需要将字节写入文件。我没有看到这样做的方法,它看起来很有用,所以我必须遗漏一些东西。有什么想法吗?

std::vector<bool> a;

a.push_back(true);
a.push_back(false);
a.push_back(false);
a.push_back(true);

a.push_back(false);
a.push_back(true);
a.push_back(true);
a.push_back(false);

9 个答案:

答案 0 :(得分:7)

std::vector <bool>实际上并不包含bools(iebytes),它包含位!这主要是一种错误,建议您使用std::deque <bool>,而不是这个“功能”。

如果您希望存储是连续的,请使用std::vector <char>

答案 1 :(得分:2)

试试这个

void WriteOut(fstream& stream, const vector<bool>& data) {
  for (vector<bool>::const_iterator it = data.begin(); it != data.end(); it++) {
    stream << *it;
  }
}

答案 2 :(得分:1)

bool通常是一个字节 - 您可以使用vector :: iterator简单地迭代向量,并以这种方式访问​​每个值。

std::vector<bool> a;

a.push_back(true);
a.push_back(false);

for(std::vector<bool>::iterator iter = a.begin(); iter != a.end(); ++iter)
{
    std::cout << *iter << std::endl;
}

将迭代每个bool,并将其打印到命令行。打印到文件相对简单。

答案 3 :(得分:1)

做这样的事情

std::vector<bool> a;
a.push_back(true);
a.push_back(false);
//...
for (auto it = a.begin(); it != a.end();) // see 0x for meaning of auto
{
    unsigned b = 0;
    for (int i = 0; i < 8*sizeof(b); ++i)
    {
        b |= (*it & 1) << (8*sizeof(b) - 1 - i);
        ++it;
    }
    // flush 'b'
}

所以,你最终做的是你将位块组合在一起,在这里我选择将位分组为本机整数(这对目标平台来说是最佳的)。我不在这里查看索引,但这是你必须要做的事情。我要做的是,我会检查我可以先提取多少个完整的块,然后执行,然后处理任何剩余的块。

另外,请注意我从左到右填充位(假设目标体系结构是little-endian),这意味着首先填充msb。

如果您正在进行位操作和类似的操作,请为您找出一个包装方案并让它成为您的数据结构。 std :: bit_vector,std :: vector或:: dequeue并不重要。将您的位巧妙地打包到目标平台的本机整数类型中,这将提供最佳性能。

答案 4 :(得分:1)

为什么不使用STL bitset呢?它具有将bitset值转换为等效long值或字符串表示的特定方法:

http://www.cppreference.com/wiki/stl/bitset/start

答案 5 :(得分:0)

首先,您想使用bit_vector而不是vector。

其次,使用bit_vector或vector无法完全按照您的要求进行操作。它们被设计为集合,它们的基础格式对您是隐藏的(因此它可能决定将每个bool存储为单个字节而不是每个字节打包为8位。

答案 6 :(得分:0)

实际上你可以这样做:

copy(yourvector.begin(), yourvector.end(), std::ostreambuf_iterator<char>(outputstream));

答案 7 :(得分:0)

我不记得是否需要<{1}} 必需,很可能不是。如果是,您可以访问其:: data()成员以访问原始字节。

答案 8 :(得分:0)

在查看了以上建议的解决方案之后,我最终只编写了一个完全正常的功能。

  // Count number of bytes needed to contain the bits
  // and then copy 8 bit block as bytes.

  void writeAsBytes(const vector<bool> & inBits, vector<uint8_t> & outBytes) {
    int bitOffset = 0;
    const int maxBitOffset = (int) inBits.size();

    const bool emitMSB = true;

    int numBytes = (int)inBits.size() / 8;
    if ((inBits.size() % 8) != 0) {
      numBytes += 1;
    }

    for (int bytei = 0; bytei < numBytes; bytei++) {
      // Consume next 8 bits

      uint8_t byteVal = 0;

      for (int biti = 0; biti < 8; biti++ ) {
        if (bitOffset >= maxBitOffset) {
          break;
        }

        bool bit = inBits[bitOffset++];

        // Flush 8 bits to backing array of bytes.
        // Note that bits can be written as either
        // LSB first (reversed) or MSB first (not reversed).

        if (emitMSB) {
          byteVal |= (bit << (7 - biti));
        } else {
          byteVal |= (bit << biti);
        }
      }

      outBytes.push_back(byteVal);
    }
  }
相关问题