An array of doubles needs to be created. Since the size is recorded in the file and is not known in advance, I dynamically allocated the memory for the array.
If the machine is also little-endian no conversion is necessary, but if it is big-endian the bytes must be reversed. To check if the machine is big-endian, the first byte of a known number can be inspected. It is possible (although very unlikely) for ints and doubles do have different endianness on the same system, so both should be checked.
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
// For detecting endianess.
// dummy_int: highest order byte is zero, lowest order byte is non-zero.
// dummy_double: highest order byte (part of exponent) is non-zero,
// lowest order byte (part of mantissa) is zero.
int32_t dummy_int = 1;
double dummy_double = 1.0;
#define INT_IS_BIG_ENDIAN (((char*) &dummy_int)[0] == 0)
#define DOUBLE_IS_BIG_ENDIAN (((char*) &dummy_double)[0] != 0)
void extract(FILE* fp, void *data, size_t size, int reverse);
void reverse_bytes(void *data, size_t size);
void display(void *data, size_t size);
int main()
{
int32_t n, i;
double *data;
FILE* fp = fopen("data","rb");
extract(fp, &n, sizeof(n), INT_IS_BIG_ENDIAN);
data = (double*) malloc(n * sizeof(double));
for (i = 0; i < n; i++) {
extract(fp, &data[i], sizeof(double), DOUBLE_IS_BIG_ENDIAN);
}
fclose(fp);
// print the data
printf("n: %d\n", n);
for (i = 0; i < n; i++) {
printf("item #%d: %f\n", i+1, data[i]);
printf("in hex: ");
display(&data[i], sizeof(double));
}
free(data);
return 0;
}
void extract(FILE* fp, void *data, size_t size, int reverse)
{
fread(data, size, 1, fp);
if (reverse) {
reverse_bytes(data, size);
}
}
void reverse_bytes(void *data, size_t size)
{
char *i, *j;
char tmp;
for (i = (char*) data, j = i + size - 1; i < j; i++, j--) {
tmp = *i;
*i = *j;
*j = tmp;
}
}
void display(void *data, size_t size)
{
size_t i;
char *char_data = (char*) data;
for (i = 0; i < size; i++) {
printf("%02x ", (unsigned char) char_data[i]);
}
printf("\n");
}