O objetivo desse trabalho é escrever uma função gravacompactado
que escreva um array de structs em um arquivo binário de forma compacta,
isto é, sem padding,
e uma função dump
para visualizar o resultado gerado.
A função gravacompactado
deve receber como argumentos
o tamanho (número de elementos) do array de structs a ser escrito em arquivo,
o array de structs propriamente dito,
uma descrição dos structs que compõem o array (descrição dos campos),
um valor indicando se os valores básicos contidos nesses campos
devem ser armazenados no arquivo
em little endian ou big endian, e um arquivo aberto,
seguindo o protótipo a seguir:
int gravacompactado ( void* valores, int tamanho, char campos[], int little, FILE *arquivo);
O array campos
armazena valores inteiros representando, na ordem,
os tipos de cada campo dos structs a serem armazenados no arquivo de acordo
com o código a seguir:
char 1 short int 2 int 3 fim 0
Como exemplo, dada a declaração:
struct s { short s1; int i1; char c1; int i2; short s2; char c2; }; struct s exemplo[10];se o array S for passado para
gravacompactado
, o argumento campos
deveria ter o valor {2,3,1,3,2,1,0}.
O formato do arquivo de saída deve ser o seguinte.
unsigned char
.
Voltando ao caso do array exemplo
, o início do arquivo ficaria assim:
| 1101 1011 | /* supondo little endian */ | 1100 100l | /* +12 bits contendo a descrição dos 6 campos */ | 0000 1010 | /* há 10 structs neste arquivo */ | xxxx xxxx | /* aqui começam os dados desses 10 structs */ | .... |
Nesse exemplo, na memória de um IA-32 executando Linux, cada struct ocuparia 20 bytes.
Ao ser armazenado em arquivo por gravacompactado
, esse mesmo
struct ocuparia 14 bytes.
A função dump
permite a visualização de um arquivo gerado
pela gravacompactado
.
Seu protótipo é simplesmente:
void dump (FILE *arquivo);A saída dessa função deve ser a seguinte (não é necessário considerar erros na entrada):
dump
seria:
little 2 short 3 int 1 char 3 int 2 short 1 char 10 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx(onde os "xx" correspondem aos valores dos campos dos structs)
Deve ser entregue um único arquivo, compacta.c
, contendo as duas
funções acima
e outras que tiverem sido desenvolvidas como auxiliares.
Esse arquivo não deve conter uma função main
.
Para testar seu programa, crie um outro arquivo, teste.c
,
contendo a função main
.
Crie seu programa executável teste
com a linha:
gcc -Wall -o teste compacta.c teste.c
Tanto o arquivo compacta.c
como teste.c
devem
conter a linha:
#include <gravacompactado.h>e o arquivo
gravacompactado.h
usado deve conter apenas os protótipos
(cabeçalhos)
das funções gravacompactado
e dump
.
compacta.c
.