Преобразует биты в читаемый формат - PullRequest
0 голосов
/ 04 марта 2019

Я хочу прочитать двоичный файл в структуру

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

Первые 16 бит двоичного файла - это тип, следующие 32 бита - длина данных, следующие - данные,В файле несколько записей, и последняя запись имеет длину 0, представляющую конец файла.

Я хочу прочитать и распечатать значения каждой записи.

Я нашел способ прочитать тип и длину, но я застрял при попытке использовать длину для чтения данных.,Кроме того, как я могу поместить это в цикл до длины = 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 голосов
/ 04 марта 2019

Вот альтернативный метод использования гибкого элемента массива:

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

Существуют некоторые предположения относительно того, что представляет длина и размер записи, но вы можете адаптировать это, чтобы соответствоватьспецифика вашей проблемы.

0 голосов
/ 04 марта 2019

Вы можете определить гибкий массив в структуре, например:

#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.

Обратите внимание на прагма-пакет # важно, поскольку он может избежать выравнивания данных компилятором в структуре, поэтому он может точно соответствовать вашему формату на диске!

...