Question

I ai une image de disque qui contient une image standard en utilisant fusible. Le superbloc contient ce qui suit, et j'ai un read_superblock de fonction (* buf) qui retourne les données brutes suivantes:

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

Je suis très nouveau à C et à me lancer sur ce projet, je suis curieux de savoir ce qui est un moyen simple de lire dans une structure ou certaines variables et simplement les imprimer à l'écran en utilisant printf pour le débogage.

Je pensais d'abord de faire quelque chose comme la pensée suivante, je pouvais voir les données brutes, mais je pense que ce n'est pas le cas. Il y a aussi pas de structure et je suis en train de le lire dans une chaîne qui semble aussi terriblement mal. pour moi de saisir des données sur. Est-il possible pour moi de préciser la structure et définir le nombre d'octets dans chaque variable?

char *buf;
read_superblock(*buf);
printf("%s", buf);
Était-ce utile?

La solution

Oui, je pense que vous seriez mieux lire ceci dans une structure. Les champs contenant des données utiles sont tous les entiers 32 bits, vous pouvez donc définir une structure qui ressemble à ceci (en utilisant les types définis dans le fichier d'en-tête standard 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;

Vous pouvez lancer la structure à un char* lors de l'appel read_superblock, comme ceci:

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

Maintenant, pour imprimer vos données, vous pouvez faire un appel comme suit:

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

Notez que vous devez être conscient de votre boutisme de la plate-forme lors de l'utilisation d'une technique comme celui-ci, puisque vous lisez des données entières (à savoir, vous devrez peut-être échanger octets lors de la lecture de vos données). Vous devriez être en mesure de déterminer que rapidement en utilisant le nombre magique dans le premier champ.

Notez qu'il est généralement préférable de passer une structure comme celui-ci sans le jeter; ce qui vous permet de profiter du type de vérification du compilateur et élimine les problèmes potentiels que la coulée peut se cacher. Cependant, cela entraînerait la modification de votre mise en œuvre de read_superblock pour lire les données directement dans une structure. Ce n'est pas difficile et peut être fait en utilisant la fonction standard d'exécution C fread (en supposant que vos données sont dans un fichier, comme le laisse entendre à votre question), comme suit:

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

Autres conseils

Deux choses à ajouter ici:

  1. Il est une bonne idée, en tirant des données brutes en un struct, pour définir la struct avoir zéro padding, même si elle est entièrement composée d'entiers non signés 32 bits. Dans gcc vous faites cela avec #pragma pack(0) avant la définition de struct et #pragma pack() après.
  2. Pour traiter les problèmes potentiels de endianness, deux appels à regarder sont ntohs() et ntohl(), et les valeurs pour 16- 32 bits respectivement. Notez que ces swaps de l'ordre des octets du réseau pour accueillir l'ordre des octets; si ceux-ci sont les mêmes (qu'ils ne sont pas sur les plates-formes x86), ils ne font rien. Vous allez d'hôte en ordre du réseau d'octets avec htons() et htonl(). Cependant, étant donné que ces données vient de votre système de fichiers et non le réseau, je ne sais pas si boutisme est un problème. Il devrait être assez facile à comprendre en comparant les valeurs que vous attendez (par exemple la taille de bloc) avec les valeurs que vous obtenez, en hexadécimal.

Il est pas difficile d'imprimer les données après les données ont été copiées dans une structure Emerick proposée. Supposons que l'instance de la structure que vous utilisez pour contenir des données est nommé SuperBlock_t_Instance.

Ensuite, vous pouvez imprimer ses champs comme ceci:

printf("Magic Number:\t%u\nBlock Size:\t%u\n etc", 
SuperBlock_t_Instance.magic_number, 
SuperBlock_t_Instance.block_size);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top