读取二进制文件并正确使用数据

时间:2014-03-29 07:49:17

标签: c binaryfiles endianness

我正在尝试编写一个C程序来显示二进制文件的内容,其中包含一些存储如下的数字: 前4个字节包含以小端格式存储的整数n。 接下来的8n个字节包含以8字节双精度格式

存储的n个浮点数的数组

"数据"用matlab制作,这个文件包括:n = 7 array = [。7147,-.2050,-.1241,1.4897,1.4090,1.4172,.6715]

到目前为止,这是我的代码。本质上我试图读取文件,通过我的小端函数发送这些变量,并显示它。我不确定为什么我会得到我得到的结果。

#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]);
      }

    }

新结果

-2103482977
1072095020
-359136765
-1077265325
-1953332745
-1077950484

不是100%确定这是否正确,但它是一个开始。不幸的是没有使用它需要的功能。

1 个答案:

答案 0 :(得分:1)

需要创建一系列双打。由于大小记录在文件中并且事先不知道,因此我动态地为数组分配了内存。

如果机器也是little-endian,则不需要转换,但如果是big-endian,则必须反转字节。要检查机器是否为big-endian,可以检查已知编号的第一个字节。对于整数和双精度,可能(虽然非常不可能)在同一系统上具有不同的字节顺序,因此应检查两者。

#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");
}