Reputation: 2171
I have some char array: char char[8]
which containing for example two ints, on first 4 indexes is first int, and on next 4 indexes there is second int.
char array[8] = {0,0,0,1,0,0,0,1};
int a = array[0-3]; // =1;
int b = array[4-8]; // =1;
How to cast this array to two int's?
There can be any other type, not necessarily int, but this is only some example:
I know i can copy this array to two char arrays which size will be 4 and then cast each of array to int. But i think this isn't nice, and breaks the principle of clean code.
Upvotes: 3
Views: 103
Reputation: 35440
Let's use a little bit of the C++ algorithms, such as std::accumulate
:
#include <numeric>
#include <iostream>
int getTotal(const char* value, int start, int end)
{
return std::accumulate(value + start, value + end, 0,
[](int n, char ch){ return n * 10 + (ch-'0');});
}
int main()
{
char value[8] = {'1','2','3','4','0','0','1','4'};
int total1 = getTotal(value, 0, 4);
int total2 = getTotal(value, 4, 8);
std::cout << total1 << " " << total2;
}
Note the usage of std::accumulate
and the lambda function. All we did was have a running total, multiplying each subtotal by 10. The character is translated to a number by simply subtracting '0'
.
Upvotes: 1
Reputation: 330
You can type cast the bytes from the array to an int *
. Then dereferencing will cause 4 bytes to be read as an int. Then doing an ntohl, will ensure that the bytes in the int are arranged as per the host order.
char array[8] = {0,0,0,1,0,0,0,1};
int a = *((int *)array);
int b = *((int *)&array[4]);
a = ntohl(a);
b = ntohl(b);
This will set a and b to 1 on both little and big endian systems.
If the compiler is set for strict aliasing, memcpy could be used to achieve the same, as follows:
char array[8] = {0,0,0,1,0,0,0,1};
int a, b;
memcpy(&a, array, sizeof(int));
memcpy(&b, array+4, sizeof(int));
a = ntohl(a);
b = ntohl(b);
Upvotes: -1
Reputation: 283634
If your data has the correct endianness, you can extract blitable types from a byte buffer with memcpy
:
int8_t array[8] = {0,0,0,1,0,0,0,1};
int32_t a, b;
memcpy(&a, array + 0, sizeof a);
memcpy(&b, array + 4, sizeof b);
While @Vivek is correct that ntohl
can be used to normalize endianness, you have to do that as a second step. Do not play games with pointers as that violates strict aliasing and leads to undefined behavior (in practice, either alignment exceptions or the optimizer discarding large portions of your code as unreachable).
int8_t array[8] = {0,0,0,1,0,0,0,1};
int32_t tmp;
memcpy(&tmp, array + 0, sizeof tmp);
int a = ntohl(tmp);
memcpy(&tmp, array + 4, sizeof tmp);
int b = ntohl(tmp);
Please note that almost all optimizing compilers are smart enough to not call a function when they see memcpy
with a small constant count argument.
Upvotes: 6