Pregunta

Tengo una imagen de disco que contiene una imagen estándar usando fusible. El superbloque contiene la siguiente, y tengo una función read_superblock (* buf) que devuelve los siguientes datos en bruto:

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

Estoy muy nuevo en C y ayuda para empezar en este proyecto soy curioso lo que es una forma sencilla de leer esto en una estructura o algunas variables y simplemente imprimirlos a la pantalla usando printf para la depuración.

Estaba pensando inicialmente de hacer algo como lo siguiente pensamiento pude ver los datos en bruto, pero creo que este no es el caso. Tampoco hay una estructura y estoy tratando de leerlo en forma de cadena que también parece muy mal. para mí para agarrar los datos de. ¿Hay alguna manera para mí especificar la estructura y definir el número de bytes en cada variable?

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

Solución

Sí, creo que sería mejor leer esto en una estructura. Los campos que contienen datos útiles son todos los números enteros de 32 bits, por lo que podrían definir una estructura que se parece a esto (utilizando los tipos definidos en el archivo de cabecera estándar 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;

Puede convertir la estructura a un char* al llamar read_superblock, como esto:

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

Ahora para imprimir sus datos, puede realizar una llamada como la siguiente:

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

Tenga en cuenta que necesita para estar al tanto de orden de bits de su plataforma cuando se utiliza una técnica de este tipo, ya que estás leyendo datos enteros (es decir, es posible que tenga que cambiar de bytes cuando la lectura de los datos). Usted debe ser capaz de determinar que rápidamente usando el número mágico en el primer campo.

Tenga en cuenta que por lo general es preferible hacer pasar una estructura como esta sin poner en ella; esto le permite tomar ventaja de la comprobación de tipos del compilador y elimina posibles problemas que pueda esconderse de fundición. Sin embargo, ello implicaría cambiar su aplicación de read_superblock para leer los datos directamente en una estructura. Esto no es difícil y se puede hacer uso de la función de tiempo de ejecución C fread estándar (suponiendo que los datos están en un archivo, como se insinúa en su pregunta), así:

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

Otros consejos

Dos cosas que añadir aquí:

  1. Es una buena idea, al tirar de datos en bruto en una estructura, para establecer la estructura para tener relleno de ceros, incluso si está compuesta en su totalidad de enteros sin signo de 32 bits. En gcc hacer esto con #pragma pack(0) antes de la definición y estructura #pragma pack() después de ella.
  2. Para hacer frente a posibles problemas endianness, dos llamadas a mirar son ntohs() y ntohl(), para valores de 16 y 32 bits respectivamente. Tenga en cuenta que éstos intercambio de orden de bytes de red hasta el host orden de bytes; Si estos son los mismos (que no están en las plataformas basadas en x86), no hacen nada. Se pasa de anfitrión a la red de orden de bytes con htons() y htonl(). Sin embargo, dado que estos datos proviene de su sistema de archivos y no en la red, no sé si endianness es un problema. Debe ser lo suficientemente fácil de averiguar mediante la comparación de los valores esperados (por ejemplo, el tamaño de bloque) con los valores que obtenga, en hexadecimal.

No es difícil de imprimir los datos después de que ha copiado con éxito los datos en una estructura Emerick propuso. Supongamos que la instancia de la estructura que se utiliza para almacenar los datos se denomina SuperBlock_t_Instance.

A continuación, puede imprimir sus campos como esto:

printf("Magic Number:\t%u\nBlock Size:\t%u\n etc", 
SuperBlock_t_Instance.magic_number, 
SuperBlock_t_Instance.block_size);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top