从 std::vector获取字节

发布于 2024-07-14 02:45:00 字数 306 浏览 2 评论 0原文

我有类似下面的内容,在用任意数量的位填充它之后,我需要获取要写入文件的字节。 我看不出有什么办法可以做到这一点,而且它似乎很有用,所以我一定错过了一些东西。 有任何想法吗?

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);

I have something like the following, and after populating it with a arbitrary number of bits, I need to get the bytes to write out to a file. I don't see a way to do this and it seems useful, so I must be missing something. Any idea's?

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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

护你周全 2024-07-21 02:45:01

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

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

First, you want to use bit_vector instead of vector.

Second, there is no way to do exactly what you want using bit_vector or vector. They are designed to be collections and their underlying format is hidden from you (thus it might decide to store each bool as an individual byte rather than packed as 8 bits per byte.

谁人与我共长歌 2024-07-21 02:45:01

实际上你可以这样做:

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

Actually you could do this:

copy(yourvector.begin(), yourvector.end(), std::ostreambuf_iterator<char>(outputstream));
尛丟丟 2024-07-21 02:45:01

在查看了上面建议的解决方案之后,我最终只编写了一个完整的工作函数。

  // 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);
    }
  }

After looking at the suggested solutions above, I ended up just writing a fully working function.

  // 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);
    }
  }
情绪 2024-07-21 02:45:01

我不记得是否需要打包 std::vector ,很可能不是。 如果是,您可以访问它的 ::data() 成员来访问原始字节。

I can't remember if an std::vector<bool> is required to be packed, most probably it's not. If it was you could access its ::data() member to have access to the raw bytes.

尬尬 2024-07-21 02:45:00

std::vector 实际上并不包含 bool(即字节),它包含位! 这主要是一个错误功能,建议您使用 std::deque,它没有此“功能”。

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

std::vector <bool> does not actually contain bools (i.e.bytes) , it contains bits! This is mostly a missfeature and you are advised to use std::deque <bool>, which doesn't have this "feature" instead.

And if you want the storage to be contiguous, use std::vector <char>.

醉城メ夜风 2024-07-21 02:45:00

尝试这个

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

Try this

void WriteOut(fstream& stream, const vector<bool>& data) {
  for (vector<bool>::const_iterator it = data.begin(); it != data.end(); it++) {
    stream << *it;
  }
}
素食主义者 2024-07-21 02:45:00

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

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

A bool is normally a byte - you can simply iterate over the vector using the vector::iterator, and access each value that way.

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

Will iterate over each bool, and print it out to the command line. Printing to a file is relatively straightforward.

梦明 2024-07-21 02:45:00

做这样的事情

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'
}

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

另外,请注意,我从左到右填充位(假设目标体系结构是小端),这意味着首先填充最高有效位。

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

Do something like this

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'
}

So, what you end up doing is that you group chunks of bits together, here I've chosen to group bits into native integers (which is optimal for the target platform). I don't check the indexes here but that's something you'll have to do. What I would do is that I would check how many full chunks I could extract first, do that and then handle any remainder.

Also, note that I'm filling in bits from left to right (assuming the target architecture is little-endian) this means filling in the msb first.

If your doing bit manipulation and stuff like that, figure out a packing scheme for you bits and let that be your data structure. std::bit_vector, std::vector or ::dequeue doesn't really matter. Pack your bits cleverly into the target platform's native integer type, that will give the best kind of performance.

影子是时光的心 2024-07-21 02:45:00

为什么不使用 STL 位集呢? 它具有将位集值转换为其等效长值或字符串表示形式的特定方法:

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

Why don't you use the STL bitset instead? It has specific methods to convert the bitset values to it equivalent long value or string representation:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文