Pergunta

Eu tenho uma imagem de disco que contém uma imagem padrão usando fusível. O Superblock contém o seguinte, e eu tenho um read_superblock função (* buf) que retorna os seguintes dados brutos:

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

Eu sou muito novo para C e para me começou neste projeto Estou curioso o que é uma maneira simples de ler isso em uma estrutura ou de algumas variáveis ??e simplesmente imprimi-los para a tela usando printf para depuração.

Eu estava inicialmente pensando em fazer algo como o seguinte pensando que eu podia ver os dados brutos, mas acho que este não é o caso. Também não há estrutura e estou tentando lê-lo como uma cadeia que também parece terrivelmente errado. para mim a dados agarrar fora de. Existe uma maneira para eu especificar a estrutura e definir o número de bytes em cada variável?

char *buf;
read_superblock(*buf);
printf("%s", buf);
Foi útil?

Solução

Sim, eu acho que você seria melhor fora de ler isso em uma estrutura. Os campos que contêm dados úteis são todos inteiros de 32 bits, para que você possa definir uma estrutura que se parece com isso (usando os tipos definidos no stdint.h arquivo de cabeçalho padrão):

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;

Você pode lançar a estrutura a um char* ao chamar read_superblock, como este:

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

Agora, para imprimir os seus dados, você pode fazer uma chamada com o seguinte:

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

Note que você precisa estar ciente de endianness de sua plataforma ao usar uma técnica como esta, desde que você está dados inteiro de leitura (ou seja, você pode precisar de swap bytes ao ler os seus dados). Você deve ser capaz de determinar que rapidamente usando o número mágico no primeiro campo.

Note que é geralmente preferível passar uma estrutura como esta, sem convertê-lo; isso permite-lhe tirar partido da verificação de tipo do compilador e elimina problemas potenciais que moldagem pode esconder. No entanto, isso implicaria mudar a sua implementação de read_superblock para ler os dados diretamente em uma estrutura. Isso não é difícil e pode ser feito usando o fread função de tempo de execução C padrão (assumindo que seus dados estão em um arquivo, como sugerido na sua pergunta), assim:

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

Outras dicas

Duas coisas a acrescentar aqui:

  1. É uma boa idéia, ao puxar dados brutos em uma estrutura, para definir a estrutura para ter zero preenchimento, mesmo que seja inteiramente composto por 32 bits inteiros sem sinal. Em gcc você fizer isso com #pragma pack(0) antes da definição struct e #pragma pack() depois.
  2. Para lidar com possíveis problemas endianness, duas chamadas para olhar são ntohs() e ntohl(), para valores de 16 e 32 bits, respectivamente. Note-se que estes troca de rede byte ordem para ordem de bytes de acolhimento; Se estes são os mesmos (o que eles não estão em plataformas baseados em x86), eles não fazem nada. Você vai de host para rede byte ordem com htons() e htonl(). No entanto, uma vez que esses dados são provenientes de seu sistema de arquivos e não a rede, eu não sei se endianness é um problema. Deve ser fácil o suficiente para descobrir comparando os valores que você espera (por exemplo, o tamanho do bloco) com os valores que você começa, em hexadecimal.

Não é difícil para imprimir os dados depois de copiado com êxito dados em uma estrutura Emerick proposto. Suponha que a instância da estrutura que você usa para dados de espera é nomeado SuperBlock_t_Instance.

Em seguida, você pode imprimir seus campos como este:

printf("Magic Number:\t%u\nBlock Size:\t%u\n etc", 
SuperBlock_t_Instance.magic_number, 
SuperBlock_t_Instance.block_size);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top