将位转换为人类可读格式

时间:2019-03-04 02:28:03

标签: c file pointers struct binary

我想将二进制文件读入结构

struct rec
{
    int type;
    long length;
    int data[100];
};

二进制文件的前16位是类型,接下来的32位是数据的长度,接下来是数据。文件中有多个记录,最后一条记录的长度为0,表示文件末尾。

我想读取并打印每条记录的值。

我想出了一种读取类型和长度的方法,但是在尝试使用长度读取数据时遇到了麻烦。另外,如何将其循环放置直到length = 0?

int main()
{
    FILE *ptr_tofile;
    struct rec some_record;
    ptr_tofile=fopen("Test.bin","rb");

    if (!ptr_tofile)
    {
        printf("Unable to open file!");
        return 1;
    }

    for ( until length = 0)
    {
        fread(&some_record, sizeof(int), 1, ptr_tofile);
        printf("%d\n",some_record.type);
        fread(&some_record, sizeof(int), 2, ptr_tofile);
        printf("%d\n",some_record.type);
        getch();
    }
    fclose(ptr_tofile);
    return 0;
}

2 个答案:

答案 0 :(得分:1)

这是使用灵活数组成员的另一种方法:

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

typedef struct file_s {
  int16_t type;
  int32_t length;
  // Assumption: Each record is 16 bits
  // For a record size of 32 bits, use int32_t*
  int16_t* data;
} file_s;

int main() {
  file_s file;
  FILE* f = fopen("file.bin","r");
  if (f == NULL) {
    perror("Error");
    return 1;
  }
  fread(&file.type, sizeof(file.type), 1, f);
  fread(&file.length, sizeof(file.length), 1, f);
  // Assumption: the length of the data is the number of records
  // If the length is in bytes, you should divide it by the size
  // of a record to obtain the number of records
  file.data = malloc(file.length * sizeof(*file.data));
  // sizeof is a compile-time operator so sizeof(*p) is not a null dereference
  fread(file.data, sizeof(*file.data), file.length, f);
  fclose(f);
  // Process the data
  /* ... */
  free(file.data);
  return 0;
}

对表示的长度和记录的大小有一些假设,但是您可以对其进行调整以适合您的问题的具体情况。

答案 1 :(得分:0)

您可以在结构中定义一个灵活的数组,例如:

#pragma pack(push, 1)
typedef struct {
    int16_t type;
    int32_t length;
    int     data[];
} record_t;
#pragma pack(pop)

,并使用以下伪代码读取一条记录。

record_t *r1;
r1 = calloc(1, sizeof(record_t));
//read the record head to r1, sizeof(record_t)
r1 = realloc(r1, r1->length*sizeof(int)+sizeof(record_t));
//read the rest of the record to r1->data, assume it is of type int.

请注意 #pragma包很重要,因为它可以避免编译器在结构中对齐数据,因此它可以完全匹配您的磁盘格式!