简体   繁体   中英

How to Extract 4 bytes of integer from a buffer of integers in c++

I have buffer/payload of integers where every 4 bytes is a field which i need to extract. I have a pointer pointing to the buffer. Now I have to extract 4 bytes and assign it to variable until I reach the end of buffer. The pointer is uint8_t pointer to the buf and buf is a buffer object whose details are encapsulated. What is the best and the most elegant way to do this? I am coding in c++. Any suggestions is appreciated.

You can do it as below using a C code:

int i = 0;
int value;
while(i < buffersize)
{
  value = 0;
  memcpy(&value, buffer, sizeof(int));
  //if the buffer is from network, then you may have to do a conversion from network order to host order here
  printf("%d", value);
  buffer = buffer + sizeof(int);
  i = i + sizeof(int);
}

I would recommend reading out the bytes one by one, and assembling the number "manually". This requires you to be clear about the expected endianness, which is a good thing. It also makes the code fine with any alignment requirements since all you read from the buffer is bytes.

uint32_t extract_uint32_be(const uint8_t *buffer)
{
  const uint8_t b0 = buffer[0], b1 = buffer[1], b2 = buffer[2], b3 = buffer[3];

  return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
}

If the integers in your buffer are word-aligned, you could try:

const char* ptr; // this points to a position in a buffer
int value = reinterpret_cast<int*>(ptr);

Otherwise, perhaps safer and more preferable:

const char* ptr;
int value;
std::copy(ptr, ptr+sizeof(int), reinterpret_cast<char*>(value));

BTW: make sure you don't have a problem with endianess (ie both your machine and the machine that saved those ints must have the same endianess for this to work, otherwise you need to compensate). You're relying on your specific implementation of C++ here.

assert(buf_bytes % 4 == 0);
std::vector<uint32_t> numbers(buf_bytes/4);
memcpy(&numbers[0], buf, buf_bytes);
if (need_byte_swap)
    std::for_each(numbers.begin(), numbers.end(), [](uint32_t &n){ntohl(n);});

转换为4字节整数和索引的数组。

Either read the bytes one at a time and shift /add them into the int or use memcpy to copy the bytes into a variable of the correct type. std::copy might be acceptable too, I'm not sure of the rules for aliasing for that.

Casting to an array as suggest likely breaks the strict aliasing rules and therefore isn't guarenteed to work and is likely undefined behavour.

You can do it as below using a C code:

i points the buffer from where 4 bytes are to be read.

 read = (UInt32)((UInt8*)p_msg)[i++] << 24;
 read |= (UInt32)((UInt8*)p_msg)[i++] << 16;
 read |= (UInt32)((UInt8*)p_msg)[i++] << 8;
 read |= (UInt32)((UInt8*)p_msg)[i++];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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