Frage

Ich habe ein Disk-Image, das ein Standard-Bild mit Sicherung enthält. Der Superblock enthält folgende, und ich habe eine Funktion read_superblock (* buf), die die folgenden Rohdaten zurückzugibt:

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

Ich bin sehr neu in C und ich an diesem Projekt zu bekommen begann ich bin gespannt, was eine einfache Möglichkeit, dies in eine Struktur oder einige Variablen zu lesen und sie einfach auf den Bildschirm für die Fehlersuche mit printf ausdrucken.

Ich dachte zunächst von etwas wie das folgende Denken zu tun ich die Rohdaten sehen konnte, aber ich denke, das ist nicht der Fall ist. Es gibt auch keine Struktur, und ich versuche, es zu lesen in als Zeichenfolge, die auch schrecklich falsch zu sein scheint. für mich Daten aus zu greifen. Gibt es eine Möglichkeit für mich, um die Struktur zu geben und die Anzahl von Bytes in jeder Variablen definieren?

char *buf;
read_superblock(*buf);
printf("%s", buf);
War es hilfreich?

Lösung

Ja, ich glaube, Sie besser dran seien, diese in eine Struktur zu lesen. Die Felder mit nützlichen Daten sind alle 32-Bit-Integer, so können Sie eine Struktur definieren, die wie folgt aussieht (die Typen mit der Standard-Header-Datei stdint.h definiert):

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;

Sie können die Struktur auf eine char* werfen, wenn read_superblock Aufruf wie folgt aus:

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

Sie nun Ihre Daten auszudrucken, wenn Sie einen Anruf wie folgt machen:

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

Beachten Sie, dass Sie von Ihrer Plattform des endianness bewusst sein müssen, wenn eine Technik, wie diese verwendet werden, da Sie Integer-Daten gerade lesen (das heißt, müssen Sie möglicherweise Bytes tauschen, wenn die Daten zu lesen). Sie sollten mit der magischen Zahl im ersten Feld, das schnell in der Lage sein, zu bestimmen.

Beachten Sie, dass es in der Regel bevorzugt, eine Struktur wie diese zu passieren, ohne sie zu werfen; dies ermöglicht es Ihnen, die Vorteile des Compilers Typprüfung zu nehmen und eliminiert potenzielle Probleme, die Gießen verstecken kann. Dies würde jedoch zur Folge hat Ihre Implementierung von read_superblock Ändern von Daten direkt in eine Struktur zu lesen. Dies ist nicht schwierig und kann unter Verwendung der Standard-C-Laufzeitfunktion fread getan werden (vorausgesetzt, Ihre Daten in einer Datei ist, wie bei in Ihrer Frage angedeutet), etwa so:

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

Andere Tipps

Zwei Dinge hinzufügen hier:

  1. Es ist eine gute Idee, wenn Rohdaten in eine Struktur ziehen, die Struktur zu setzen Nullen haben, auch wenn es vollständig auf 32-Bit-Integer ohne Vorzeichen zusammengesetzt ist. In gcc tun Sie dies mit #pragma pack(0) vor der struct Definition und #pragma pack() danach.
  2. Für mit potentiellen endianness Fragen beschäftigen, zwei Anrufe zu betrachten sind ntohs() und ntohl(), für 16- und 32-Bit-Werte sind. Beachten Sie, dass diese Swap von Netzwerk-Byteordnung auszurichten; wenn diese die gleichen sind (was sie nicht auf x86-basierten Plattformen sind), tun sie nichts. Sie gehen von der Host-Byte-Reihenfolge mit htons() und htonl() zu vernetzen. Da jedoch diese Daten von Ihrem Dateisystem kommen und nicht das Netz, weiß ich nicht, ob endianness ein Problem. Es sollte einfach genug sein, um herauszufinden, um die Werte zu vergleichen Sie (zum Beispiel der Blockgröße) mit den Werten, die Sie in hex bekommen, erwarten.

Es ist nicht schwierig, die Daten zu drucken, nachdem Sie erfolgreich Daten in eine Struktur kopiert Emerick vorgeschlagen. Angenommen, die Instanz der Struktur, die Sie Daten zu halten, verwenden benannt SuperBlock_t_Instance.

Dann können Sie die Felder wie folgt drucken:

printf("Magic Number:\t%u\nBlock Size:\t%u\n etc", 
SuperBlock_t_Instance.magic_number, 
SuperBlock_t_Instance.block_size);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top