O objetivo do trabalho é implementar, na linguagem C, uma função
(gravacomp
)
que escreve um array de structs em um
arquivo binário de forma compacta (isto é, sem padding)
e uma função (dump
) que permite visualizar
um arquivo gerado por gravacomp
.
Leia com atenção o enunciado do trabalho e as instruções para a entrega. Em caso de dúvidas, não invente. Pergunte!
gravacomp
:int gravacomp (int nstructs, void* valores, char *campos, FILE *arquivo);A função
gravacomp
recebe como argumentos:
nstructs
: o tamanho (número de elementos) do array de structs
a ser escrito em arquivo
valores
: um ponteiro para o array de structs propriamente dito
campos
: uma descrição dos campos das structs que compõem o array
arquivo
: um arquivo aberto para escrita, em modo binário
A string campos
representa, na ordem, o tipo de cada campo
das structs, de acordo com o código a seguir:
'c' - char 's' - short int 'i' - int 'p' - ponteiro
Como exemplo, dada a declaração:
struct s { short s1; int i1; char c1; char *p1; int i2; short s2; char c2; }; struct s exemplo[10];a string
campos
correspondente é "sicpisc"
.
Assumindo que o descritor do arquivo de saída está armazenado em uma variável
arq
, do tipo FILE *
, a chamada
para a gravação do array exemplo
seria:
res = gravacomp(10, &exemplo, "sicpisc", arq);
O primeiro byte do cabeçalho indica o número de structs armazenadas no arquivo,
como um unsigned char
.
A seguir aparecem os descritores de campos dos structs, cada um com 3 bits.
Cada descritor é codificado da seguinte forma:
001 - char 010 - short int 100 - int 101 - ponteiroO padrão
000
marca o final da lista de campos.
A porção não utilizada do último byte de cabeçalho (se houver) deve ser
ignorada (ou seja, o inicio dos dados propriamente ditos deve estar
alinhado no próximo byte do arquivo).
Após o cabeçalho aparecem os bytes com os dados do array de structs, armazenados no arquivo em big-endian. Não devem ser escritos no arquivo os bytes relativos a padding.
Voltando ao caso do array exemplo
, o início do arquivo ficaria assim:
| 0000 1010 | /* há 10 structs neste arquivo */ | 0101 0000 | /* aqui começa a descrição dos campos */ | 1101 1000 | | 1000 1000 | | xxxx xxxx | /* aqui começam os dados das 10 structs */
Nesse exemplo, na memória de um IA-32 executando Linux, cada struct ocuparia
24 bytes.
Ao ser armazenada em arquivo por gravacomp
, essa mesma
struct ocuparia 18 bytes.
dump
:void dump (FILE *arquivo);
A função dump
permite a visualização, na saída padrão,
de um arquivo criado por gravacomp
.
Essa saída pode ser gerada, por exemplo, através de chamadas
a printf
.
O único argumento de dump
é o descritor de
um arquivo aberto para leitura,
em modo binário. Não é necessário considerar erros na leitura desse arquivo.
A saída da função dump
deve ser a seguinte:
gravacomp
dump
seria:
10 sicpisc 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 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 (em hexa) dos bytes armazenados)
compacta.c
contendo as duas funções descritas acima (gravacomp e dump
)
e funções auxiliares, se for o caso.
Esse arquivo não
deve conter uma função main
!
Crie também um arquivo
compacta.h
,
que deve conter apenas
os protótipos (cabeçalhos) das funções gravacomp
e dump
.
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 -m32 -o teste compacta.c teste.c
Tanto o arquivo compacta.c
como
teste.c
devem conter a linha:
#include <compacta.h>
Coloque no início dos arquivos fonte, como comentário, os nomes dos integrantes do grupo, da seguinte forma:
/* Nome_do_Aluno1 Matricula Turma */ /* Nome_do_Aluno2 Matricula Turma */Coloque também no relatório o nome dos integrantes do grupo.
O trabalho deve ser enviado por email para o professor da turma, com subject/assunto "Trabalho 1 - Software Basico". Indique claramente os integrantes do grupo no corpo do email e inclua, como anexo, os três arquivos pedidos (compacta.c, teste.c e relatorio).