Domanda

Ho un immagine disco che contiene un'immagine standard con fusibile. Il superblocco contiene la seguente, e ho una funzione di read_superblock (* buf) che restituisce i seguenti dati grezzi:

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

Sono molto nuovo per C e per ottenere mi ha iniziato a questo progetto sono curioso quello che è un modo semplice per leggere questo in una struttura o di alcune variabili e semplicemente stamparli sullo schermo utilizzando printf per il debug.

Mi è stato inizialmente pensando di fare qualcosa di simile alla seguente pensiero ho potuto vedere i dati grezzi, ma penso che questo non è il caso. Non v'è inoltre alcuna struttura e sto cercando di leggerla come una stringa che sembra anche terribilmente sbagliato. per me, per afferrare i dati fuori. C'è un modo per me di specificare la struttura e definire il numero di byte in ogni variabile?

char *buf;
read_superblock(*buf);
printf("%s", buf);
È stato utile?

Soluzione

Sì, penso che sarebbe meglio la lettura di questo in una struttura. I campi contenenti dati utili sono tutti interi a 32 bit, così si potrebbe definire una struttura che assomiglia a questo (utilizzando i tipi definiti nel stdint.h file di intestazione standard):

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;

Si può lanciare la struttura ad un char* quando si chiama read_superblock, in questo modo:

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

Ora di stampare i dati, è possibile effettuare una chiamata come il seguente:

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

Si noti che è necessario essere a conoscenza di endianness della vostra piattaforma quando si utilizza una tecnica di questo tipo, dal momento che stai leggendo i dati interi (vale a dire, potrebbe essere necessario scambiare i byte durante la lettura dei dati). Si dovrebbe essere in grado di determinare che rapidamente utilizzando il numero magico nel primo campo.

Si noti che di solito è preferibile passare una struttura come questa, senza il cast; questo permette di sfruttare i vantaggi di tipo controllo del compilatore ed elimina i potenziali problemi che getto può nascondere. Tuttavia, ciò comporterebbe cambiare la realizzazione di read_superblock per leggere i dati direttamente in una struttura. Questo non è difficile e può essere fatto utilizzando la funzione di runtime C fread standard (supponendo i dati sono in un file, come accennato in questione), in questo modo:

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

Altri suggerimenti

Due cose da aggiungere qui:

  1. E 'una buona idea, quando si tira dati grezzi in una struttura, per impostare la struttura per avere zero padding, anche se è interamente composto di 32 bit interi senza segno. In gcc si esegue questa operazione con #pragma pack(0) prima della definizione struct e #pragma pack() dopo di esso.
  2. Per trattare con potenziali problemi di endianness, due chiamate da guardare sono ntohs() e ntohl(), per i valori di 16 e 32 bit, rispettivamente. Si noti che questi swap dal byte order di rete per ospitare l'ordine dei byte; se questi sono gli stessi (che non sono su piattaforme x86), non fanno nulla. Si va da host di rete byte order con htons() e htonl(). Tuttavia, dal momento che questi dati proviene dal vostro file system e non la rete, non so se endianness è un problema. Dovrebbe essere abbastanza facile da capire, confrontando i valori che ci si aspetta (ad esempio la dimensione del blocco) con i valori si ottiene, in esadecimale.

Non è difficile per stampare i dati dopo aver copiato i dati in una struttura Emerick proposto. Supponiamo che l'istanza della struttura che si utilizza per contenere i dati è denominato SuperBlock_t_Instance.

Quindi è possibile stampare i suoi campi in questo modo:

printf("Magic Number:\t%u\nBlock Size:\t%u\n etc", 
SuperBlock_t_Instance.magic_number, 
SuperBlock_t_Instance.block_size);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top