I am trying to write a C program to read in a block of instrumentation data and pull out specific bytes into variables. Data is of mixed format such as bytes 4-5 are an integer
, bytes
10-14 a float, etc.
I wrote an experimental program to test extracting values from a byte (char) array and I don't understand the results. My test program is running on a Raspberry Pi 3 running Debian Jessie.
Here is my program:
Convert byte array to parts
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
// Test Data Array
unsigned char v1[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x40, 0xB1, 0x10, 0x55, 0xEE, 0x5A, 0xC7, 0x39,
0xBB, 0x22, 0x04, 0xB2, 0xF4, 0xF5, 0xF6, 0xF7,
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFF, 0x87};
signed char c; // 1-byte
unsigned char u; // 1-byte
signed short i; // 2-byte
unsigned short j; // 2-byte
signed int k; // 4-byte
unsigned int l; // 4-byte
signed long long m; // 8-byte
unsigned long long n; // 8-byte
float x; // 4-byte
double y; // 8-byte
long double z; // 8-byte
// Display type sizes
printf("\nsizeof's: %u %u %u %u %u %u %u %u \n\n",sizeof(char),
sizeof(short),sizeof(int),sizeof(long),sizeof(long long),
sizeof(float),sizeof(double),sizeof(long double));
printf("Addresses: \n");
printf(" %08X\n %08X\n %08X\n %08X\n %08X\n %08X\n %08X\n %08X\n %08X\n %08X\n %08X\n\n",
&c,&u,&i,&j,&k,&l,&m,&n,&x,&y,&z);
// Display Endianess
unsigned int e1 = 1;
char *e2 = (char *)&e1;
if (*e2)
printf("Little Endian\n\n");
else
printf("Big Endian\n\n");
// Copy bytes to assorted variables
memcpy(&i,&v1[30],2);
printf("Signed Short: %04X %hd\n",i,i); // FF 87
memcpy(&j,&v1[30],2);
printf("Unsigned Short: %04X %hu\n",j,j); // FF 87
memcpy(&k,&v1[16],4);
printf("Signed Int: %08X %d\n",k,k); // BB 22 04 B2
memcpy(&l,&v1[16],4);
printf("Unsigned Int: %08X %u\n",l,l); // BB 22 04 B2
memcpy(&x,&v1[8],4);
printf("Float: %08X %f\n",x,x); // 40 B1 10 55
memcpy(&y,&v1[8],8);
printf("Double: %16X %lf\n",y,y); // 40 B1 10 55 EE 5A C7 39
}
The results I get:
pi@raspberrypi:~/Desktop $ ./convertIt_bytes2
sizeof's: 1 2 4 4 8 4 8 8
Addresses: 7EA7E5DB 7EA7E5DA 7EA7E5D8 7EA7E5D6 7EA7E5D0 7EA7E5CC 7EA7E5C0 7EA7E5B8 7EA7E5B4 7EA7E5A8 7EA7E5A0
Little Endian
Signed Short: FFFF87FF -30721
Unsigned Short: 87FF 34815
Signed Int: B20422BB -1308351813
Unsigned Int: B20422BB 2986615483
Float: 7EA7E5E8 9943184834560.000000
Double: 7EA7E5EC 0.000000
The type sizes used with memcpy
look correct from my printout of sizeof's
so why is my output only partially correct? The Signed Short
hex value is printed with 8 characters instead of 4 even though it's a 2-byte word printed with %04X
.
The subsequent unsigned short and int outputs are correct, but the following float and double hex values are garbage and appear to be addresses
not values as the outputs are close to the variable addresses printed above. What is going on?