5

我有一个vector<unsigned char>并且想将一个 4 字节Integer放入前 4 个元素中。在 C++ 中是否有比这样的屏蔽更简单的方法:

myVector.at(0) = myInt & 0x000000FF;
myVector.at(1) = myInt & 0x0000FF00;
myVector.at(2) = myInt & 0x00FF0000;
myVector.at(3) = myInt & 0xFF000000;
4

5 回答 5

12

Astd::vector保证被存储为一个连续的数据块(‡)。因此,可以以std::vector<unsigned char>基本相同的方式将 a 视为unsigned char缓冲区。这意味着,您可以memcpy将数据放入向量中,前提是您确定它足够大:

#include <vector>
#include <cstring>
#include <cstdint>

int main()
{
  std::int32_t k = 1294323;
  std::vector<unsigned char> charvec;

  if (charvec.size() < sizeof(k))
    charvec.resize(sizeof(k));

  std::memcpy(charvec.data(), &k, sizeof(k));

  return 0;
}

注意:data()函数std::vector将 a 返回void*到向量的内部缓冲区。它在 C++11 中可用——在早期版本中,可以使用向量的第一个元素的地址来&charvec[0]代替。

当然这是一种非常不寻常的使用 a 的方式std::vector,并且(由于必要的resize())有点危险。我相信你有充分的理由想要这样做。


(‡)或者,正如标准所说:

(§23.3.6.1/1)[...] 向量的元素是连续存储的,这意味着如果v是 a vector<T, Allocator>whereT是 以外的某种类型bool,那么它服从恒等式

       &v[n] == &v[0] + n for all 0 <= n < v.size().
于 2013-06-04T08:27:18.483 回答
4

您必须二进制转换您的值才能使其工作:

myVector.at(0) = (myInt & 0xFF);
myVector.at(1) = (myInt >> 8) & 0xFF;
myVector.at(2) = (myInt >> 16) & 0xFF;
myVector.at(3) = (myInt >> 24) & 0xFF;

你的代码是错误的:

int myInt = 0x12345678;
myVector.at(0) = myInt & 0x000000FF; // puts 0x78 
myVector.at(1) = myInt & 0x0000FF00; // tries to put 0x5600 but puts 0x00
myVector.at(2) = myInt & 0x00FF0000; // tries to put 0x340000 but puts 0x00
myVector.at(3) = myInt & 0xFF000000; // tries to put 0x12000000 but puts 0x00
于 2013-06-04T08:23:35.533 回答
2

您可以执行类似于以下的操作:

#include <vector>
#include <cstdio>

void
insert_int(std::vector<unsigned char>* container, int integer)
{
    char* chars = reinterpret_cast<char*>(&integer);
    container->insert(container->end(), chars, chars+sizeof(int));
}

int main(void)
{
    std::vector<unsigned char> test_vector;
    int test_int = 0x01020304;

    insert_int(&test_vector, test_int);

    return 0;
}

只要记住要考虑endieness。我的机器以相反的顺序打印 int。 4,3,2,1

于 2013-06-04T08:27:45.320 回答
1

这是最紧凑的方式:

myVector.at(0) = *((char*)&myInt+0);
myVector.at(1) = *((char*)&myInt+1);
myVector.at(2) = *((char*)&myInt+2);
myVector.at(3) = *((char*)&myInt+3);
于 2013-06-04T08:54:07.737 回答
1

您的解决方案不正确,因为您目前拥有它。就像是:

std::vector<unsigned char> v(sizeof(int));
int myInt = 0x12345678;

for(unsigned i = 0; i < sizeof(int); ++i) {
    v[i] = myInt & 0xFF;
    myInt >>= 8;
}

应该管用。它也更便携(不假设int是 4 个字节)。

于 2013-06-04T08:28:49.003 回答