Вопрос

У меня есть образ диска, который содержит стандартный образ с использованием предохранителя.Суперблок содержит следующее, и у меня есть функция read_superblock(*buf), которая возвращает следующие необработанные данные:

Bytes 0-3: Magic Number (0xC0000112)
      4-7: Block Size (1024)
     8-11: Total file system size (in blocks)
    12-15: FAT length (in blocks)
    16-19: Root Directory (block number)
  20-1023: NOT USED

Я новичок в C, и чтобы начать работу над этим проектом, мне интересно, каков простой способ прочитать это в структуре или некоторых переменных и просто распечатать их на экран, используя printf для отладки.

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

char *buf;
read_superblock(*buf);
printf("%s", buf);
Это было полезно?

Решение

Да, я думаю, вам лучше записать это в структуру.Все поля, содержащие полезные данные, представляют собой 32-битные целые числа, поэтому вы можете определить структуру, которая выглядит следующим образом (используя типы, определенные в стандартном заголовочном файле stdint.h):

typedef struct SuperBlock_Struct {
  uint32_t magic_number;
  uint32_t block_size;
  uint32_t fs_size;
  uint32_t fat_length;
  uint32_t root_dir;
} SuperBlock_t;

Вы можете привести структуру к char* при звонке read_superblock, так:

SuperBlock_t sb;
read_superblock((char*) &sb);

Теперь, чтобы распечатать ваши данные, вы можете сделать вызов следующим образом:

printf("%d %d %d %d\n",
  sb.magic_number,
  sb.block_size,
  sb.fs_size,
  sb.fat_length,
  sb.root_dir);

Обратите внимание, что при использовании такого метода вам необходимо учитывать порядок байтов вашей платформы, поскольку вы читаете целочисленные данные (т. е. вам может потребоваться поменять местами байты при чтении ваших данных).Вы сможете быстро это определить, используя магическое число в первом поле.

Обратите внимание, что обычно предпочтительнее передавать такую ​​структуру без ее приведения;это позволяет вам воспользоваться преимуществами проверки типов компилятором и устраняет потенциальные проблемы, которые могут скрыть приведение типов.Однако это повлечет за собой изменение вашей реализации read_superblock для чтения данных непосредственно в структуру.Это несложно и может быть сделано с помощью стандартной функции времени выполнения C. fread (при условии, что ваши данные находятся в файле, как указано в вашем вопросе), вот так:

fread(&sb.magic_number, sizeof(sb.magic_number), 1, fp);
fread(&sb.block_size, sizeof(sb.block_size), 1, fp);
...

Другие советы

Сюда следует добавить две вещи:

  1. При добавлении необработанных данных в структуру рекомендуется установить для структуры нулевое заполнение, даже если она полностью состоит из 32-битных целых чисел без знака.В gcc вы делаете это с помощью #pragma pack(0) перед определением структуры и #pragma pack() после этого.
  2. Для решения потенциальных проблем с порядком байтов необходимо рассмотреть два вызова: ntohs() и ntohl(), для 16- и 32-битных значений соответственно.Обратите внимание, что порядок байтов в сети меняется на порядок байтов хоста;если они одинаковы (чего нет на платформах на базе x86), они ничего не делают.Вы переходите от хоста к сетевому порядку байтов с помощью htons() и htonl().Однако, поскольку эти данные поступают из вашей файловой системы, а не из сети, я не знаю, является ли проблемой порядок байтов.Это должно быть достаточно легко выяснить, сравнив ожидаемые значения (например,размер блока) с полученными значениями в шестнадцатеричном формате.

Распечатать данные после того, как вы успешно скопировали их в структуру, предложенную Эмериком, несложно.Предположим, экземпляр структуры, которую вы используете для хранения данных, называется SuperBlock_t_Instance.

Затем вы можете распечатать его поля следующим образом:

printf("Magic Number:\t%u\nBlock Size:\t%u\n etc", 
SuperBlock_t_Instance.magic_number, 
SuperBlock_t_Instance.block_size);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top