C++ 在向量的前4个字符元素中放入一个4字节的整数

C++ 在向量的前4个字符元素中放入一个4字节的整数,c++,vector,integer,bitmask,C++,Vector,Integer,Bitmask,我有一个向量,想在前四个元素中放入一个4字节的整数。 C++中有比这样的掩蔽更简单的方法: myVector.at(0) = myInt & 0x000000FF; myVector.at(1) = myInt & 0x0000FF00; myVector.at(2) = myInt & 0x00FF0000; myVector.at(3) = myInt & 0xFF000000; 您必须对值进行二进制移位才能使其生效: myVector.at(0) = (m

我有一个
向量
,想在前四个元素中放入一个4字节的
整数。
C++中有比这样的掩蔽更简单的方法:

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

您必须对值进行二进制移位才能使其生效:

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

保证将
std::vector
存储为一个连续的数据块(‡)。因此,可以用与
无符号字符
缓冲区基本相同的方式来处理
std::vector
。这意味着您可以
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;
}

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

#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;
}
#包括
#包括
无效的
insert_int(标准::向量*容器,整数)
{
char*chars=reinterpret_cast(&integer);
container->insert(container->end(),chars,chars+sizeof(int));
}
内部主(空)
{
std::向量测试\向量;
int test_int=0x01020304;
插入_int(&test_向量,test_int);
返回0;
}
记住要考虑到持久性。我的机器按相反的顺序打印int。
4,3,2,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;
}
标准向量v(sizeof(int)); int myInt=0x12345678; for(无符号i=0;i>=8; }

应该有用。它的可移植性也更高(不假定
int
为4字节)。

以下是最简洁的方法:

myVector.at(0) = *((char*)&myInt+0);
myVector.at(1) = *((char*)&myInt+1);
myVector.at(2) = *((char*)&myInt+2);
myVector.at(3) = *((char*)&myInt+3);

获取指向第一个元素的指针并重新解释它?但我不是100%相信那不是UB。。。(你考虑过字节顺序吗?)你到底想在这里实现什么?这感觉真是个糟糕的主意。你忘了向右移动吗?@BoBTFish,在你的情况下,行为至少取决于endianness。向量包含通过USB发送的数据,前4个字节包含有效负载数据的长度。字节顺序已处理。@BoBTFish
reinterpret\u cast
通常不正确的原因是向量内的
unsigned char*
缓冲区的对齐可能不够严格。对于<代码>未签名的char *CARBUF,执行<代码> RealTytPrase:C++(CARBUF)>代码>,然后仅允许如果结果是<代码> CabBuf 对齐。我也喜欢这种样式,但是谨防嵌入式系统上的类型双关,因为这可能导致字节对齐问题的未定义行为。仍然没有一个真正的缓冲区类可以与Go或Java相媲美,我觉得这样的东西很有必要。然而,我不喜欢memcpy方法的一点是,它将以主机字节顺序存储数据,而不是以定义良好的字节顺序存储数据,这在将其用于网络/文件IO时非常有用。@Niklaschnelle很抱歉在此征求意见,但我认为memcopy方法没有问题。99.9%的编译时间用于特定主机,或者至少用于具有相同endianess的主机。具有不同Endianness的CPU将具有完全不同的指令集。至于网络/文件I/O,有一些预定义的标准是可以的,就像在Java中一样,但Java是不可知平台的。有了这样一个endian强制,它所匹配的处理器会感到高兴,并且会因为所有的字节交换而把其他的处理器打得一塌糊涂。所以这里没有真正的胜利。
myVector.at(0) = *((char*)&myInt+0);
myVector.at(1) = *((char*)&myInt+1);
myVector.at(2) = *((char*)&myInt+2);
myVector.at(3) = *((char*)&myInt+3);