Reputation: 367
Let's say I have the following array of bytes:
uint8_t barr[4] = {0xCE, 0xCE, 0xCE, 0xCE};
Given an index n
, I want to be able to read two bytes:
uint16_t d16 = barr[0];
And have d16
be equal to
0xCECE
Perhaps there is a function in the standard library that can perform such task?
Upvotes: 2
Views: 4772
Reputation: 70931
A linear and endianness-safe approach here:
#include <stdint.h>
#include <stdio.h>
#include <arpa/inet.h> /* for ntohs() */
union Convert
{
uint16_t to_integer_big_endian;
uint8_t barr[sizeof (uint16_t)];
};
uint16_t pick_and_convert(uint8_t * barr, size_t s, size_t n)
{
union Convert c = {0}; /* Take out-of-bound bytes as 0s. */
for (size_t i = 0; i < sizeof c.barr && (n + i) < s; ++i)
{
c.barr[i] = barr[n + i];
}
return ntohs(c.to_integer_big_endian);
}
int main(void)
{
uint8_t barr[4] = {1, 2, 3, 4}; /* Assuming a binary sequence. */
size_t n;
scanf("%zu", &n);
uint16_t to_integer = pick_and_convert(barr, sizeof barr / sizeof *barr, n);
printf("result = 0x%hx\n", to_integer);
}
Upvotes: 0
Reputation: 37227
A piece of cake:
memcpy(&d16, barr + n, sizeof(d16));
Don't try to convert pointers or use union
s. Those either are undefined behaviors, or may trip trap representations. memcpy()
is the "canonical" solution (as the C++ boost library does).
Upvotes: 9