Domanda

I am trying to write a C program to display the content of a binary file which contains a few numbers stored as follows: The first 4 bytes contain an integer n stored in little endian format. The next 8n bytes contain an array of n floating point numbers stored in 8 byte double precision format

"Data" was made with matlab, and this file includes: n = 7 array = [.7147, -.2050, -.1241, 1.4897, 1.4090, 1.4172, .6715]

So far this is the code that I have. Essentially I am trying to read in the file, send those variables through my little endian function, and display it. I'm not sure why I'm getting the outcome that I'm getting.

#include <stdio.h>
#include <stdint.h>

/* function to show bytes in memory, from location str to str+n*/
void extract_little(char *str,int offs, int n); 
void extract_big(char *str,int offs, int n);
/*Main function to call above function */
int ofset;

int main(){


int x;
int i[numE*4];
FILE* fp = fopen("data","rb");

fread(i,sizeof(i[x]),numE,fp);
fclose(fp);
for (x=1; x < numE;x++)
printf("%d%\n",i[x]);

//extract_little((char *)&i, ofset, sizeof(i));

  return 0;

}


  void extract_little(char *str,int offs, int n) 
    {
    int i;
    for (i = 0; i < n; i++){
       printf(" %04f\n\n", (unsigned int) str[i]);
      }

    }

New Outcome

-2103482977
1072095020
-359136765
-1077265325
-1953332745
-1077950484

Not 100% sure if this is correct, but it's a start. Unfortunately not utilizing the function, which it needs to.

È stato utile?

Soluzione

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");
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top