Sei sulla pagina 1di 36

Escola de Engenharia

Departamento
Informtica

de

Engenharia

Mestrado Integrado em Engenharia


Informtica
Laboratrios de Informtica III

Relatrio de Laboratrios de
Informtica III
GereVendas
(Trabalho Prtico de C)
Grupo 1:
Joo Martins (A68646)

Joo Pereira (A75273)

Manel Castro (A71646)

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

ndice
1.

Mdulos de dados......................................................................................................3
Bool................................................................................................................................3
Venda.............................................................................................................................3
AVL................................................................................................................................3
Tipos enumerados......................................................................................................3
Typedefs de funes....................................................................................................4
Estruturas de dados e tipos exportados......................................................................5
Funes da API..........................................................................................................6
Cliente............................................................................................................................7
Estruturas de dados....................................................................................................7
Funes da API..........................................................................................................8
Produto...........................................................................................................................8
Estruturas de dados....................................................................................................9
Funes da API..........................................................................................................9
LStrings........................................................................................................................10
Estruturas de dados..................................................................................................10
Nmero de Strings por pgina..................................................................................11
Funes da API.........................................................................................................11
CatalogoClientes..........................................................................................................12
Estruturas de dados..................................................................................................12
Funes da API........................................................................................................14
CatalogoProds..............................................................................................................15
Estruturas de dados..................................................................................................15
Funes da API........................................................................................................16
FaturacaoGlobal...........................................................................................................17
Macros......................................................................................................................17
Estruturas de dados..................................................................................................17
Definio de tipos....................................................................................................19
Funes da API........................................................................................................19
Filial.............................................................................................................................22
MemUtils.....................................................................................................................23
Funes da API........................................................................................................23
Leitura..........................................................................................................................23
Macros......................................................................................................................23
Funes da API........................................................................................................24

4. Mdulo principal (main.c)...........................................................................................24


1

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Estruturas de dados......................................................................................................24
Leitura dos ficheiros e invocao das queries.............................................................25
Ficheiros lidos por omisso......................................................................................25

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

1. Mdulos de dados
Bool
O standard C89 (tambm conhecido como ANSI C) no define o tipo bool, pelo que
optamos por criar um pequeno ficheiro designado por bool.h, onde inclumos as
seguintes definies:

Este tipo foi utilizado em todos os mdulos em que existem variveis, parmetros ou
valores de retorno que s podem tomar os valores lgicos TRUE ou FALSE.

Venda
Para evitar que o utilizador tenha que utilizar valores numricos ao se referir a cada um
dos tipos de venda, optamos por criar um pequeno mdulo de dados, designado por
venda.h, onde colocamos as seguintes definies:

Ficando assim definidos o nmero de tipos de venda (N_TIPOS_VENDA) e o tipo


enumerado TipoVenda, que passam a poder ser utilizados em qualquer mdulo que faa
referncia aos dois tipos de vendas.

AVL
A necessidade de ler e consultar grandes volumes de dados tornou indispensvel a
utilizao de estruturas de dados nas quais a insero e a procura sejam eficientes. Por
esse motivo, optamos pela utilizao de rvores AVL genricas para armazenar a maior
parte da informao lida a partir dos ficheiros de dados, garantindo assim que cada
operao de insero ou procura seja realizada em tempo O(log n) .
Tipos enumerados
Para assinalar o fator de balano de cada nodo de uma AVL, definimos o tipo
enumerado FatorBalanco. Note-se que o utilizador do mdulo de AVLs no necessita
de ter informao relativa ao fator de balano dos nodos da AVL que est a utilizar, pelo
que a definio deste tipo enumerado foi colocada em AVL.c, sendo expressa por:
3

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

typedef enum fatorBalanco {ESQ, EQ, DIR} FatorBalanco;


Typedefs de funes
Dada a generalidade das AVLs utilizadas e a necessidade de comparao entre os
valores de nodos em operaes como a insero, procura e travessia inorder de uma
AVL, definimos a assinatura da funo de comparao que o utilizador deve fornecer
aquando da criao de uma rvore AVL. Esta definio tem que ser conhecida pelo
utilizador, pelo que est disponvel no ficheiro avl.h, estando expressa por:
typedef void (*Comparador) (void *, void *);
Nota: A funo de comparao deve devolver um valor < 0 se o 1 argumento for
menor que o 2, um valor = 0 se os dois argumentos forem iguais e > 0 se o 1
argumento for maior que o 2.
Alm desta definio, temos tambm a definio dos seguintes tipos de funes:

Funo que atualiza o valor de um nodo de uma AVL:


typedef void (*Atualizador) (void *, void *);
, onde o valor apontado pelo 1 argumento atualizado com base no valor
apontado pelo 2 argumento.

Funo usada para criar uma cpia do valor armazenado num dado nodo de uma
AVL:
typedef void* (*Duplicador) (void *);

Funo que liberta a memria alocada para o valor guardado no nodo de uma
AVL:
typedef void (*LibertarNodo) (void *);

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Estruturas de dados e tipos exportados


No ficheiro avl.c encontra-se a definio de duas estruturas de dados:
TCD_AVL:
typedef struct TCD_AVL{
AVL_NODO* raiz;
Atualizador atualiza;
Comparador compara;
Duplicador duplica;
LibertarNodo liberta;
int tamanho;
} TCD_AVL;
raiz apontador para a raiz da
AVL;
atualizador apontador para uma
funo que permite atualizar o
valor de um nodo da AVL. Se este
apontador for NULL, a AVL
permite repeties de valores;
compara apontador para a
funo de comparao entre os
valores de 2 nodos de uma AVL;
duplicador apontador para uma
funo que devolve uma cpia do
valor de um nodo.
liberta apontador para uma
funo que liberta a memria
alocada para o valor guardado num
nodo. Se este for NULL, usada a
funo free().
Tamanho n de nodos da AVL.

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

AVL_NODO:
typedef struct nodoAVL{
void* valor;
FatorBalanco fatorBalanco;
struct
nodoAVL
*esquerda,
*direita;
} AVL_NODO;

valor referncia do valor do nodo;


fatorBalanco fator de balano do nodo
(ESQ, EQ ou DIR);
esquerda apontador para a raiz da
subrvore esquerda ou para NULL, se esta
no existir;
direita apontador para a raiz da
subrvore direita ou para NULL, se esta
no existir;

Ao colocarmos estas definies apenas no ficheiro avl.c estamos a preservar o


encapsulamento, escondendo a implementao concreta das estruturas de dados
utilizadas e evitando o acesso direto s mesmas. O utilizador, ao ter apenas acesso ao
ficheiro avl.h, s conhece a declarao abstrata do tipo AVL:
typedef struct TCD_AVL* AVL;
Assim, qualquer tentativa por parte do utilizador de desreferenciar um apontador para a
struct TCD_AVL provoca um erro de compilao, pelo que a nica forma de manipular
uma AVL utilizar as funes da sua API que apresentamos de seguida.

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Funes da API

AVL criaAVL (
Atualizador atualiza,
Comparador compara,
Duplicador duplica,
LibertarNodo liberta
)
Cria uma AVL vazia, que vai utilizar a funo de comparao 'compara'. A funo
de comparao obrigatria. As restantes funes so opcionais. Se no for
fornecida uma funo de atualizao, a AVL criada admite repeties. Se no for
passada uma funo de libertao de nodos, a AVL criada utiliza a funo free()
para libertar cada nodo.
AVISO: Se o utilizador no passar uma funo de duplicao, no criada uma
cpia aquando da insero de um valor na AVL e as funes inorderAVL() e
procuraAVL() devolvem o contedo da prpria AVL!
Retorna:
Em caso de sucesso retornada a AVL criada. Quando no fornecida uma
funo de comparao ou h uma falha de alocao, devolvido NULL.

AVL insereAVL (AVL arvore, void* val)

Insere um valor numa AVL previamente criada. Caso tenha sido passado um
duplicador aquando da criao da arvore, o valor inserido uma cpia do
original. Caso contrrio, o original.
Retorna:
rvore com o valor inserido em caso de sucesso. NULL em casos de falha de
alocao.

AVL apagaAVL (AVL arvore)


Liberta a memria alocada para guardar a AVL passada como parmetro.
Retorna:
sempre retornado NULL.

int tamanhoAVL (const AVL arvore)


Retorna:
Nmero de nodos da AVL passada como parmetro.

int alturaAVL (const AVL arvore)

Retorna:
Altura da AVL passada como parmetro.
void** inorderAVL(const AVL arvore)
Retorna:
Em caso de sucesso, devolvido um array com os valores dos nodos (cpias
se a funo de duplicao tiver sido passada durante a criao da AVL)
resultante da travessia inorder da AVL. Caso contrrio, devolvido NULL.

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

void* procuraAVL (const AVL arv, void* val)


Procura o valor val (2 argumento) na AVL arv (1 argumento)
Retorna:
Se o valor procurado existir na AVL e tiver sido passada uma funo de duplicao aquando da
criao da AVL, devolvida uma cpia do valor existente na AVL. Se o valor existir mas a AVL
no tiver uma funo de duplicao, devolvido o prprio valor que est na AVL. Nos restantes
casos devolvido NULL.

bool existeAVL(const AVL arv, void* val)


Testa se o valor val (2 argumento) existe na AVL arv (1 argumento).
Retorna:
TRUE se o val existir na AVL arv. FALSE caso contrrio.

Nota: o tipo AVL o nico tipo acessvel ao exterior e as funes da API no fazem
qualquer referncia a TCD_AVL.

Cliente
O tipo Cliente foi definido para esconder do utilizador a representao interna do
cdigo de cada cliente, permitindo ao mesmo tempo que a API dos restantes mdulos
que lidam com clientes seja mais sugestiva e agradvel.
Estruturas de dados
No ficheiro cliente.c podemos encontrar a definio da estrutura de dados ilustrada a
seguir:
Cliente:
struct cliente {
char* codigoCliente;
};
codigoCliente apontador para o
cdigo do cliente. Sendo declarado
como um char*, o cdigo de
cliente pode ter qualquer dimenso,
uma vez que aponta para uma
String alocada com a funo
Embora a nica informao armazenada na struct cliente seja um apontador para o
cdigo do cliente, o utilizador da API no tem que saber o que est guardado dentro
desta struct, pelo que no ficheiro cliente.h temos apenas:
typedef struct cliente* Cliente;
Deste modo, garantimos que o tipo Cliente opaco, o que leva a que o utilizador s o
possa manipular atravs das funes da API que passamos a descrever.

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Funes da API

Cliente criaCliente (char* codigoCliente)


Cria um cliente com o cdigo passado como parmetro.
Retorna:
O cliente criado em caso de sucesso. NULL em caso de falha de alocao.

Cliente apagaCliente (Cliente c)


Liberta a memria alocada para guardar um cliente.
Retorna:
sempre retornado NULL.

char * obterCodigoCliente (Cliente c)


Retorna:
Em caso de sucesso, devolvida uma cpia do cdigo do cliente passado como parmetro. Se
ocorrer uma falha de alocao, devolvido NULL.

char inicioCodigoCliente (Cliente c)

Retorna:
1 letra do cdigo do cliente passado como parmetro.
int comparaCodigosCliente (Cliente c1, Cliente c2)
Compara os cdigos de dois clientes.
Retorna:
devolvido um valor < 0 se o cdigo de c1 for menor que o de c2, = 0 se os
cdigos de c1 e c2 forem iguais e > 0 se o cdigo de c1 for maior que o de
c2.

Cliente duplicaCliente (Cliente c)


Retorna:
Em caso de sucesso devolvida uma cpia do cliente passado como
parmetro. Se ocorrer uma falha de alocao devolvido NULL.

Produto
O tipo Produto , em termos estruturais, semelhante ao tipo Cliente e tambm foi
definido pelas mesmas razes que o tipo Cliente, i.e.: esconder a representao interna
do cdigo de cada produto e tornar a API dos restantes mdulos que lidam com
produtos mais sugestiva.

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Estruturas de dados
No ficheiro produto.c encontra-se a definio da estrutura de dados a seguir ilustrada:
Produto:
struct produto {
char* codigoProduto;
};
codigoProduto apontador para o
cdigo
do
produto.
Sendo
declarado como um char*, o
cdigo de produto pode ter
qualquer dimenso, uma vez que
aponta para uma String alocada
Analogamente struct cliente, a nica informao armazenada na struct produto um
apontador para o cdigo do produto, mas o utilizador, tendo apenas acesso ao ficheiro
produto.h s conhece a seguinte definio do tipo abstrato de dados Produto:
typedef struct produto* Produto;
Logo o tipo produto tambm opaco.
Funes da API

Produto criaProduto (char* codigoProduto)


Cria um produto com o cdigo passado como parmetro.
Retorna:
O produto criado em caso de sucesso. NULL em caso de falha de alocao.

Produto apagaProduto (Produto p)


Liberta a memria alocada para guardar um produto.
Retorna:
sempre retornado NULL.

char* obterCodigoProduto (Produto p)


Retorna:
Em caso de sucesso devolvida uma cpia do cdigo do produto passado como parmetro. Se
ocorrer uma falha de alocao, devolvido NULL.

char inicioCodigoProduto (Produto p)


Retorna:
1 letra do cdigo do produto passado como parmetro.

10

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

int comparaCodigosProduto (Produto p1, Produto p2)


Compara os cdigos de dois produtos.
Retorna:
devolvido um valor < 0 se o cdigo de p1 for menor que o de p2, = 0 se os
cdigos de p1 e p2 forem iguais e > 0 se o cdigo de p1 for maior que o de
p2.

Produto duplicaProduto (Produto p)


Retorna:
Em caso de sucesso devolvida uma cpia do produto passado como
parmetro. Se ocorrer uma falha de alocao devolvido NULL.

LStrings
A grande quantidade de dados na forma de Strings, devolvidos por algumas das funes
das APIs que sero apresentadas a seguir, tornou necessrio o desenvolvimento de uma
estrutura de dados navegvel com a noo de ndice e de pgina. Como a estrutura
descrita no fundo uma lista de Strings genrica, o grupo designou-a por LStrings.
Uma vez criada, uma LStrings permite que o utilizador decida se pretende ir para a
pgina seguinte, para a pgina anterior, para uma pgina sua escolha ou ento para a
primeira ou ltima pgina. Estando na pgina pretendida, o utilizador pode ento pedir
para obter uma cpia dos contedos dessa pgina e em seguida pode obter os contedos
dessa pgina, linha a linha.
Estruturas de dados
No ficheiro LStrings.c, encontram-se as definies dos tipos concretos de dados
utilizados para implementar a lista de Strings e o tipo pgina:
LStrings:

Pagina:

struct lStrings{
int total;
char** strings;
int pag;
int ndice;
};

struct pagina{
int total;
char** strings;
int ndice;
};

total nmero de Strings da lista de total nmero total de Strings na pgina;


Strings;
strings array com as Strings da pgina;
strings array de Strings com os indice ndice da String em que nos
contedos da lista;
encontramos num dado momento;
pag pgina atual;
ndice ndice da primeira String da
pgina atual;

11

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Mais uma vez, a implementao de cada uma das estruturas de dados apresentada foi
escondida do utilizador declarando no ficheiro .h os tipos abstratos de dados como
apontadores para os respetivos tipos concretos de dados, i.e.:
typedef struct lStrings* LStrings;
typedef struct pagina* Pagina;
Ficando assim assegurada a opacidade dos tipos LStrings e Pagina.
Nmero de Strings por pgina
O nmero de Strings por pgina de cada LStrings criada fixo e est definido no
ficheiro LStrings.h, da seguinte forma:

Funes da API

LStrings criaLStrings (int total, char *strings[])


Cria uma LStrings com de tamanho igual a total, cujas Strings so cpias de
cada um dos elementos de strings.Se total for menor ou igual a 0, criada uma
lista vazia.
Retorna:
Para total >= 0 devolvida, em caso de sucesso, uma LStrings com o
nmero de elementos especificados, cujos contedos so cpias dos
elementos do array strings. Para total < 0, em caso de sucesso, devolvida
uma LStrings vazia. Se ocorrer uma falha de alocao, devolvido NULL.
.

LStrings apagaLStrings (LStrings l)


Liberta a memria alocada para armazenar uma LStrings.
Retorna:
sempre devolvido NULL.

Pagina obterPag (LStrings l)


Retorna:
Cpia da pgina atual de uma LStrings (ou NULL em caso de falha de
alocao).

char * obterLinha (Pagina pag)


Retorna:
Cpia da prxima linha de uma pgina (ou NULL em caso de falha de
alocao).

Pagina apagaPag (Pagina pag)


Liberta a memria alocada para uma pgina.

12

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Retorna:
sempre retornado NULL.

13

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

int obterNumPag (LStrings l)


Retorna:
Nmero da pgina atual da LStrings passada como parmetro.

int obterTotal (LStrings l)


Retorna:
Nmero total de Strings na LStrings passada como parmetro.

int obterNumTotalPags (LStrings l)


Retorna:
Nmero total de pginas da LStrings.passada como parmetro.

void proxPag (LStrings l)


Dada uma LStrings, passa para a pgina seguinte da mesma, caso a pgina
atual no seja a ltima. Se a lista estiver na ltima pgina, esta funo no tem
qualquer efeito.

void pagAnt (LStrings l)


Dada uma LStrings, passa para a pgina anterior da mesma, caso a pgina
atual no seja a primeira. Se a lista estiver na primeira pgina, esta funo no
tem qualquer efeito.

void irParaPag (int pag, LStrings l)


Dada uma LStrings e uma pgina pag, vai para a pgina escolhida se esta for
vlida. Se pag for invlida, esta funo no tem qualquer efeito.

void primPag (LStrings l)


Coloca uma LStrings na sua primeira pgina.

void ultimaPag (LStrings l)


Coloca uma LStrings na sua ltima pgina.

CatalogoClientes
O mdulo catalogoClientes tem todas as funes e estruturas de dados utilizadas para
guardar, por ordem alfabtica, todos os clientes lidos a partir do ficheiro clientes.txt.
Estruturas de dados
Tendo em considerao o facto de cada cdigo de cliente comear por uma letra
maiscula e de existirem 26 iniciais possveis, o grupo optou por estruturar o catlogo
de clientes como um array de 26 AVLs que na posio de ndice 0 tem uma AVL com
todos os clientes cujo cdigo comea por A, na posio de ndice 1 tem uma AVL com
todos os clientes cujo cdigo comea por B e assim sucessivamente. Estruturar o
catlogo de clientes desta forma tem a vantagem de permitir inseres e procuras
bastante mais eficientes, dado que em vez de termos uma AVL com todos os cdigos de
clientes temos 26 AVLs em que cada uma relativamente pequena. Esta estruturao
tambm facilita a obteno de todos os cdigos de cliente comeados por uma dada
14

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

letra.
Partindo da anlise exposta no pargrafo anterior, o grupo declarou a struct
catClientes-no ficheiro catalogoClientes.c, cuja ilustrao passamos a apresentar:
struct catClientes {
AVL catalogo[MAX_AVL];
};
MAX_AVL macro que
corresponde ao valor 26;
catalogo array de 26 AVLs. A
AVL na posio de ndice 0 tem os
clientes cujo cdigo comea por
A, a posio de ndice 1 tem os
clientes com cdigo comeado por
B e assim sucessivamente;
[0]
Clientes cujo cdigo
comea por A

[1]
Clientes cujo cdigo
comea por B

[25]
Clientes cujo cdigo
comea por Z

"A2652
"

"A1319"

"A1300"

"A3938"

"A2646"

"A3984"

Nota: embora vrias funes da API do catlogo de clientes recebam um elemento do


tipo Cliente, a nica informao que precisamos de guardar no catlogo o cdigo de
cada cliente. Assim sendo, cada nodo das AVLs da struct catClientes tem apenas uma
String correspondente ao cdigo de um determinado cliente.
A implementao concreta do catlogo de clientes foi ocultada do utilizador atravs da
declarao, no ficheiro .h, do tipo abstrato CatClientes como sendo um apontador para
15

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

a struct catClientes. Assim, catalogoClientes.h temos a expresso:


typedef struct catClientes* CatClientes;

16

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Funes da API

CatClientes criaCatClientes ()
Aloca espao e inicializa um novo catlogo de clientes.
Retorna:
Um catlogo de clientes vazio em caso de sucesso. NULL em caso de falha de alocao.

CatClientes insereCliente (CatClientes, Cliente)


Recebe um catlogo de clientes e um cliente. Insere o cliente no catlogo
passado para a funo.
Retorna:
Em caso de sucesso devolvido o catlogo de clientes aps a insero. Caso contrrio,
devolvido NULL.

bool existeCliente (CatClientes, Cliente)


Testa se um cliente existe num catlogo de clientes.
Retorna:
TRUE se o cliente existir no catlogo passado como parmetro. FALSE caso contrrio.

int totalClientes (CatClientes)


Retorna:
Nmero total de clientes no catlogo de clientes passado como parmetro.

int totalClientesLetra (CatClientes catC, char)


Recebe um catlogo de clientes e um carater.
Retorna:
Nmero total de clientes no catlogo passado como parmetro cujo cdigo
comea pela letra especificada.

CatClientes apagaCatClientes (CatClientes)


Liberta a memria alocada para um catlogo de clientes.
Retorna:
sempre devolvido NULL.

Cliente* todosClientes (CatClientes catC)


Retorna:
Array de elementos do tipo Cliente, com todos os clientes do catlogo passado como parmetro.
Nota: o encapsulamento dos dados garantido pelo facto de no serem devolvidos os elementos do
catlogo de clientes, mas sim novos elementos do tipo Cliente, criados a partir de cada um dos
cdigos de cliente existentes no catlogo catC.

LStrings clientesPorLetra (CatClientes, char)


Recebe um catlogo de clientes e uma letra
Retorna:
Lista de Strings navegvel (LStrings) com os cdigos dos clientes
comeados pela letra especificada no 2 argumento.

17

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

CatalogoProds
O mdulo catalogoProds semelhante ao mdulo catalogoClientes, visto que contm
as estruturas que permitem guardar, por ordem alfabtica, todos os produtos lidos a
partir do ficheiro produtos.txt.
Estruturas de dados
Os cdigos de produto, tal como os cdigos de cliente, comeam por uma das 26 letras
maisculas do alfabeto. Alm disso, o tipo de operaes que se pretende realizar sobre
um catlogo de produtos idntico ao tipo de operaes efetuadas sobre um catlogo de
clientes, logo a estruturao que escolhemos para o catlogo de produtos idntica
que j foi apresentada para o catlogo de clientes.
A nica diferena relativamente ao catlogo de clientes que neste caso estamos a
guardar cdigos de produtos e portanto temos uma estrutura designada por struct
catProds-no ficheiro catalogoProdutos.c, que pode ser ilustrada por:
struct catProds{
AVL catalogo[MAX_AVL];
};
MAX_AVL macro que
corresponde ao valor 26;
catalogo array de 26 AVLs. A
AVL na posio de ndice 0 tem os
produtos cujo cdigo comea por
A, a posio de ndice 1 tem os
produtos com cdigo comeado
por B e assim sucessivamente;
[0]
Produtos cujo cdigo
comea por A

[1]
Produtos cujo cdigo
comea por B

[25]
Produtos cujo cdigo
comea por Z

Nota: cada nodo das AVLs da struct catProds tem apenas uma String correspondente
ao cdigo de um determinado produto.
A definio do tipo abstrato de dados do catlogo de produtos tambm semelhante s
restantes definies de TADs apresentadas anteriormente, pelo que temos, no ficheiro
catalogoProdutos.h, a linha:
typedef struct catProds* CatProds;

18

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Funes da API

CatProds criaCatProds ()
Aloca espao e inicializa um novo catlogo de produtos.
Retorna:
Um catlogo de produtos vazio em caso de sucesso. NULL em caso de falha de alocao.

CatProds insereProduto (CatProds, Produto)


Recebe um catlogo de produto e um produto. Insere o produto no catlogo
passado para a funo.
Retorna:
Em caso de sucesso devolvido o catlogo de produtos aps a insero. Caso contrrio,
devolvido NULL.

bool existeProduto (CatProds, Cliente)


Testa se um produto existe num catlogo de produtos.
Retorna:
TRUE se o produto existir no catlogo passado como parmetro. FALSE caso contrrio.

int totalProdutos (CatProds)


Retorna:
Nmero total de produtos no catlogo de produtos passado como parmetro.

int totalProdutosLetra (CatProds catP, char)


Recebe um catlogo de produtos e um carater.
Retorna:
Nmero total de produtos no catlogo passado como parmetro cujo cdigo
comea pela letra especificada.

CatProds apagaCatProds (CatProds)


Liberta a memria alocada para um catlogo de produtos.
Retorna:
sempre devolvido NULL.

LStrings prodsPorLetra (CatProds, char)


Recebe um catlogo de produtos e uma letra
Retorna:
Lista de Strings navegvel (LStrings) com os cdigos dos produtos
comeados pela letra especificada no 2 argumento.

19

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

FaturacaoGlobal
O mdulo FaturacaoGlobal permite obter informaes relativas s vendas mensais
e/ou anuais dos vrios produtos, como:
O total de vendas e total faturado com um produto num dado ms, em modo
Normal (N) e em Promoo (P) (query 3);
A lista ordenada dos cdigos de produtos que ningum comprou (query 4);
Total de vendas e total faturado num intervalo fechado de meses (query 6);
Quais foram os N produtos mais vendidos do ano (query 10);
A faturao global possibilita tambm a distino das vendas/faturao de cada filial e
referencia todos os produtos, mesmo os no vendidos, de forma a garantir uma resposta
eficiente query 4. Note-se, contudo, que no feita qualquer referncia a clientes e
qualquer informao relativa aos mesmos deve ser obtida no mdulo Filial.
Macros
No ficheiro faturcaoGlobal.c definimos as seguintes macros:

Estruturas de dados
Ao analisarmos as queries a que a faturao global deve ser capaz de responder
constatamos que duas delas (as queries 3 e 6) tm como chave de pesquisa o ms,
enquanto que as outras duas (as queries 4 e 10) requerem informaes sobre as vendas
do ano. Tendo estes aspetos em considerao, optamos por ter duas estruturas principais
distintas na faturao global:
Uma estrutura em que so referenciados todos os produtos e que permite obter
informao relativa s vendas anuais de cada um deles, para cada filial;
Uma estrutura que tem informao sobre as vendas de cada ms e que permite
distinguir compras N de compras P, bem como as vendas/faturao de cada
filial;

20

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Partindo da anlise acima descrita, optamos pela seguinte estruturao dos dados:
FaturacaoGlobal:

FatAnualProd
todosProdutos)

(nodo

da

AVL

struct fatGlobal{
AVL todosProdutos; struct fatAnualProd{
FatMes
char* prod;
fatMensal[N_MESES+1];
int
};
totalUnids[N_FILIAIS+1];
todosProdutos

AVL }; com
informao sobre as vendas anuais de
todos os produtos;
prod String com o cdigo de um
fatMensal array de estruturas
produto;
com
informao relativas faturao
totalUnids
de
array que na posio
cada ms;
de ndice i tem o nmero de unidades
do produto prod vendidas durante o
Nota: o array fatMensal
ano na
temfilial i;
comprimento N_MESES+1 para que
o possamos comear a indexar a
partir da posio de ndice 1.
FatMes:
struct fatMes{
int totalVendas;
double totalFaturado;
AVL fatProds;
};
totalVendas total de vendas do ms;
totalFaturado total faturado no ms;
fatProds AVL com informao sobre a faturao de cada um dos produtos
vendidos no ms;

FatProdMes (nodo da AVL fatProds)


struct fatProdMes{
char* prod;
int unidsVend[N_TIPOS_VENDA][N_FILIAIS+1];
double faturacao[N_TIPOS_VENDA][N_FILIAIS+1];
};
prod String com o cdigo do produto vendido;
unidsVend matriz que na linha 0 tem a quantidade vendida do produto prod em
vendas normais, para cada filial, e na linha 1 tem a quantidade vendida em
promoo, para cada filial;
faturacao matriz anloga a unidsVend, que guarda informao sobre a faturao
de prod;

21

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Definio de tipos
Tipos auxiliares (i.e.: definidos em faturacaoGlobal.c)
As structs fatMes e fatAnualProd so estruturas auxiliares. O utilizador no necessita
de ter conhecimento das mesmas para obter as vrias informaes que possa desejar
sobre a faturao dos produtos. Por esse motivo, a definio dos tipos FatMes e
FatAnualProd foi colocada no ficheiro faturacaoGlobal.c, sendo expressa por:
typedef struct fatMes* FatMes;
typedef struct fatAnualProd* FatAnualProd;
Tipos exportados (i.e.: definidos em faturacaoGlobal.h)
O utilizador ter naturalmente que conhecer o tipo abstrato de dados FaturacaoGlobal,
logo no ficheiro faturacaoGlobal.h temos:
typedef struct fatGlobal FaturacaoGlobal;
O grupo optou tambm por exportar o tipo abstrato FatProdMes, que no mais do que
a referncia da struct fatProdMes, cuja implementao o utilizador desconhece. Assim,
no ficheiro faturacaoGlobal.h temos tambm:
typedef struct fatProdMes FatProdMes;
A razo para exportamos este tipo est relacionada com a query 3, uma vez que nesta
query o utilizador precisa de obter, para um dado produto e um dado ms, o total
faturado em modos N e P (podendo optar por obter resultados globais ou por filial).
Ora, a struct fatProdMes tem todas essas informaes, portanto optamos por permitir
que o utilizador obtenha, com a funo obterFatProdMes(), a referncia da struct
fatProdMes para o produto e ms que pretende. Posto isto, o utilizador pode, com
algumas das funes da API da faturao global, obter informao relativa aos campos
que pretende. importante notar que o tipo FatProdMes opaco, logo o utilizador no
tem conhecimento sobre a sua implementao, no consegue desreferenci-lo e tem
obrigatoriamente que usar as funes disponibilizadas na API de forma a conseguir as
informaes que deseja.
Funes da API

FaturacaoGlobal criaFaturacaoGlobal ()

Cria a faturao global.


Retorna:
A faturao global criada em caso de sucesso. NULL em caso de falha de
alocao.

FaturacaoGlobal apagaFaturacaoGlobal (FaturacaoGlobal fg)


Liberta a memria alocada para armazenar a faturao global.
Retorna:
sempre retornado NULL.

22

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

1. FaturacaoGlobal registaProduto (FaturacaoGlobal fg, Produto p)

Regista um produto na faturao global.


Retorna:
A faturao global aps a insero, em caso de sucesso. NULL em caso de
falha de alocao.

FaturacaoGlobal registaVenda (
FaturacaoGlobal fg,
Produto p,
double precoUnit,
int quantidade,
TipoVenda tipo,
int filial,
int ms
)
Regista uma venda na faturao global.
Retorna:
A faturao global aps a insero, em caso de sucesso. NULL em caso de
falha de alocao.

int totalVendasMes (const FaturacaoGlobal fg, int mes)


Retorna:
Total de vendas num dado ms.

double totalFaturadoMes (const FaturacaoGlobal fg, int mes)


Retorna:
Total faturado num dado ms.

int totalVendasIntervMeses (const FaturacaoGlobal fg, int inicio, int fim)


Recebe uma faturao global e o incio e o fim de um intervalo fechado meses.
Retorna:
Total de vendas registadas no intervalo de meses [inicio, fim].
Nota: se inicio for maior que fim, considera-se que o intervalo um conjunto
vazio, pelo que o total de vendas retornado nesses casos 0.

double totalFatIntervMeses (const FaturacaoGlobal fg, int inicio, int fim)


Recebe uma faturao global e o incio e o fim de um intervalo fechado meses.
Retorna:
Total faturado no intervalo fechado de meses [inicio, fim].
Nota: tal como na funo totalVendasIntervMeses(), se inicio for maior que
fim, considera-se que o intervalo um conjunto vazio, pelo que a faturao total
retornada nesses casos 0.

FatProdMes obterFatProdMes (const FaturacaoGlobal fg, const Produto p, int


mes)
Recebe uma faturao global, um produto e um ms.

23

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Retorna:
Cpia da faturao do produto p, no ms especificado, em caso de sucesso.
NULL
em caso de falha de alocao..

FatProdMes apagaFatProdMes (FatProdMes fProdMes)


Liberta a memria alocada para guardar o resultado de obterFatProdMes().
Retorna:
sempre retornado NULL.

int totalUnidsProdMes (const FatProdMes fProdMes, TipoVenda tipo)


Recebe a faturao de um produto num ms (obtida com obterFatProdMes())
e um tipo de venda.
Retorna:
Total de unidades vendidas globalmente, que esto registadas em fProdMes,
para o tipo de venda escolhido.

int * unidsPorFilialProdMes (const FatProdMes fProdMes, TipoVenda tipo)


Recebe a faturao de um produto num ms (obtida com obterFatProdMes())
e um tipo de venda.
Retorna:
Array de que na posio de ndice i tem o nmero de vendas registadas em
fProdMes, para a filial i e para o tipo de venda escolhido.
Nota: de forma a preservar o encapsulamento, o array devolvido uma cpia
daquele que se encontra em fProdMes.

double faturacaoTotalProdMes (const FatProdMes fProdMes, TipoVenda tipo)


Recebe a faturao de um produto num ms (obtida com obterFatProdMes())
e um tipo de venda.
Retorna:
Faturao total a nvel global, registada em fProdMes, para o tipo de venda
escolhido.

double * faturacaoPorFilialProdMes (const FatProdMes fProdMes, TipoVenda


tipo)
Recebe a faturao de um produto num ms (obtida com obterFatProdMes())
e um tipo de venda.
Retorna:
Array de que na posio de ndice i tem a faturao total registada em
fProdMes, para a filial i e para o tipo de venda escolhido.
Nota: de forma a preservar o encapsulamento, o array devolvido uma cpia
daquele que se encontra em fProdMes.

int quantosNaoComprados (const FaturacaoGlobal fg)


Recebe uma faturao global.
Retorna:

24

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Nmero de produtos que no foram comprados em nenhuma filial, durante o


ano.

25

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

LStrings naoCompradosGlobal (const FaturacaoGlobal fg)

Recebe uma faturao global.


Retorna:
Lista de Strings navegvel com os produtos que no foram comprados em
nenhuma f
filial, durante o ano.
LStrings * naoCompradosPorFilial (const FaturacaoGlobal fg)
Recebe uma faturao global.
Retorna:
Array de lista de strings em que a lista na posio i tem os cdigos de todos
os produtos que no foram comprados durante o ano na filial i.

char ** NmaisVendidosFilial (const FaturacaoGlobal fg, int N, int filial)


Recebe uma faturao global, uma filial e um nmero 'N'.
Retorna:
Array com os cdigos dos 'N' produtos mais vendidos nessa filial, ordenados
decrescentemente pelo total de vendas.

Filial
O mdulo Filial permite obter informaes relativas s compras realizadas
por cada cliente, discriminando os cdigos dos produtos comprados por
cada cliente, o ms e a filial onde foram comprados, os tipos de compras
que foram realizados (P e/ou N), o total gasto na compra desses produtos e
o total de unidades compradas desse produto por ms. Este mdulo foi
estruturado com o objetivo de ter uma resposta eficiente s seguintes
queries:

N total de produtos comprados pelo cliente, ms a ms e por


filial (Query 5);
Lista ordenada de cdigos de cliente que realizaram compras
em todas as filiais (Query 7)
Cdigos e n total de clientes que compraram um produto,
distinguindo as compras P das N (Query 8);
Lista de cdigos de produto que um cliente mais comprou
(Query 9);
Calcular os N produtos mais vendidos em todo o ano, indicando
para cada filial, o total de clientes que o compraram e o total de
unidades vendidas(Query10)
Cdigo dos 3 produtos em que um cliente mais gastou dinheiro
durante o ano (Query 11)
Nmero de clientes que no realizaram compras e nmero de
produtos no vendidos (Query 12).

Nota: neste mdulo s se faz referencia a clientes que fizeram compras e a


produtos que foram efetivamente comprados, de maneira a tornar a
estrutura mais leve e tornar as travessias/procuras na rvore mais rpidas.

Estruturas de dados
Analisando as queries, rapidamente se percebe que a chave principal de pesquisa neste
26

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

mdulo o cdigo de clientes, uma vez que 5 das 6 queries que fazem uso deste mdulo
tm como uma das chaves o cdigo de cliente. Atendendo a isto, estruturamos a Filial
da seguinte forma:
Definies dos tipos:
Como vimos anteriormente, existem 2 tipos(alias) para AVL's de forma a clarificar o
tipo dos nodos:
typedef AVL AVL_ComprasPorCliente;
typedef AVL AVL_ComprasDoProduto;
Estes tipos esto definidos no ficheiro filial.c e no faz sentido que estejam no ficheiro
filial.h porque o utilizador da API no precisa sequer de saber que estamos a
implementar o mdulo custa de AVLs.
O nico tipo exportado deste mdulo o tipo Filial, definido como:
typedef struct filial* Filial;
Como o ficheiro filial.h no revela a constituio das estruturas, mantemos o tipo Filial
completamente opaco aos utilizadores da API. Atravs das funes da API definidas
abaixo, conseguimos obter toda a informao que precisamos para as queries, a partir de
uma varivel do tipo Filial.
Funes da API

Filial criaFilial ()

Aloca espao e inicializa uma Filial.


Retorna:
A filial criada, em caso de sucesso. NULL em caso de falha de alocao.
Filial apagaFilial (Filial filial)
Liberta o espao alocado para guardar uma Filial.
Retorna:
sempre devolvido NULL.

Filial registaCompra (
Filial filial,
Cliente cliente,
Produto produto,
int mes,
TipoVenda tipoVenda,
int unidades,
double preco

)
Regista os dados de uma compra numa filial.
Retorna:
A filial resultante, em caso de sucesso. NULL em caso de falha de alocao.

27

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

int* unidadesClientePorMes (Filial filial, Cliente cliente)


Retorna:
Em caso de sucesso devolvido um array com 13 entradas (12 vlidas) em que a entrada i
guarda o nmero de unidades compradas no ms i pelo cliente escolhido. Em caso de falha de
alocao, devolvido NULL.

Cliente* clientesCompraramNaFilial (Filial filial)


Recebe uma Filial.
Retorna:
Array com os clientes que compraram na Filial passada como parmetro para a funo.

bool clienteComprouNaFilial (Filial filial, Cliente cliente)


Retorna:
TRUE se o cliente passado como 2 argumento tiver feito pelo menos uma compra na filial
passada como 1 argumento. FALSE c.c.

int quantosClientesCompraram (Filial filial)

Retorna:
Nmero total de clientes que compraram na filial passada como parmetro.

LStrings produtosClienteMaisComprou (Filial filial, Cliente c, int mes)


Recebe uma Filial, um cliente e um ms.
Retorna:
Em caso de sucesso, devolvida uma lista de Strings com os cdigos de produto que o cliente
mais comprou (por quantidade) nessa filial. Em caso de falha de alocao devolvido NULL.

char ** tresProdsEmQueMaisGastou (Filial filial, Cliente c)


Recebe uma Filial e um cliente.
Retorna:
Em caso de sucesso devolvido um array com os cdigos dos 3 produtos em que o cliente
passado como parmetro gastou mais dinheiro durante o ano, ordenados decrescentemente pelo
total gasto neles. Em caso de falha de alocao, devolvido NULL.

void comprou (Filial filial, Cliente cliente, Produto produto, bool *comprouN, bool *comprouP)
Dado um cliente, uma Filial e um produto, verifica se o cliente comprou em modo Normal e se
comprou em modo de promoo. Os resultados so guardados em cada uma das variveis passadas
por referncia.

int numeroClientesCompraramProduto (Filial filial, char *produto, int *unidadesCompradas)


Recebe uma Filial e um cdigo de Cliente.
Retorna:
Nmero de clientes que compraram o Produto. A quantidade comprada devolvida na varivel
apontada por unidadesCompradas.

28

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

2. Mdulo de alocao/desalocao de memria


MemUtils
A necessidade frequente de alocar arrays de estruturas e de os libertar quando j no so
necessrios levou o grupo a criar o mdulo MemUtils, de forma a simplificar o cdigo
dos restantes mdulos e torn-lo mais legvel e fcil de manter.
Funes da API

void ** alocaMatriz (int nlinhas, int ncolunas, size_t nBytesElem)

Aloca memria para armazenar uma matriz genrica, de dimenses nlinhas X


ncolunas em que o nmero de bytes de cada elemento dado por nBytesElem
(3 argumento).
Retorna:
Em caso de sucesso devolvida a matriz alocada. Se ocorrer uma falha de
alocao devolvido NULL.
void apagaArray (void* array[], int total, void(*apagaElem)(void *))
Recebe um array de apontadores, o seu nmero total de elementos e a
referncia de uma funo apagaElem(), a utilizar para libertar cada elemento do
array. Liberta a memria alocada para guardar o array passado como 1
argumento.

3. Mdulo auxiliar de leitura e processamento de


input
Leitura
No mdulo principal (main.c) do programa GereVendas bastante frequente termos
que ler linhas e em seguida remover o(s) seu(s) caratere(s) de newline, sendo tambm
bastante comum termos que ler inteiros ou simplesmente um nico carater. Todo este
cdigo de leitura e processamento de input poderia ser colocado na main.c, mas nesse
caso estaramos a repetir cdigo e a tornar a main.c mais extensa do que o necessrio.
Para evitar essa repetio de cdigo e de forma a agrupar as funes mais gerais de
leitura e processamento de input, criamos o mdulo leitura.c + leitura.h, cujas macros
e API apresentamos de seguida.
Macros

A macro FLUSH_STDIN() utilizada para consumir os carateres que ficam no buffer


do stdin, quando parte de uma linha introduzida pelo utilizador no consumida. Deste
modo, evita-se que as leituras do standard input recebam como input carateres que
ficaram no buffer do stdin no final da leitura anterior.

29

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Funes da API

char* leLinha (char buffer[], int tamanho, FILE* stream)


L a partir de uma stream uma linha com o tamanho especificado no 2
argumento e guarda-a no buffer passado como 1 argumento, sem o(s)
caratere(s) de newline. So lidos no mximo 'tamanho' 1 carateres, porque o
tlimo carater o '\0'. Se a stream for o stdin e ficarem caratres no buffer do
mesmo aps a leitura da linha, feito o flush do stdin.
Retorna:
Se for lido o EOF antes de qualquer outra carater, a funo leLinha() devolve
NULL, se no, devolve a linha lida.

int avancaEspacosInicio (char str[])


Recebe uma String.
Retorna:
ndice do primeiro carater da Strings passada como parmetro que no um
espao. A definio de espao est de acordo com a da funo isspace() de
<ctype.h>.

int leInt ()
L um valor inteiro do stdin e faz o flush do mesmo, se necessrio.
Retorna:
Inteiro lido. Se no for possvel converter os carateres introduzidos para um
valor interiro, devolvido 0.

double leDouble ()
L um double do stdin e faz o flush do mesmo, se necessrio.
Retorna:
Double lido. Se no for possvel converter os carateres introduzidos para um
double, devolvido 0.

int leChar ()
L um carater do stdin e faz o flush do mesmo, se necessrio.
Retorna:
devolvido o carater lido, em caso de sucesso. Em caso de erro ou de end of
file, devolvido EOF.

4. Mdulo principal (main.c)


Uma vez apresentados os mdulos de dados, leitura e alocao de memria, passamos
agora para a exposio dos aspetos mais importantes do mdulo principal do programa
GereVendas.

Estruturas de dados
Todas as estruturas de dados utilizadas no ficheiro main.c so importadas dos vrios
mdulos de dados expostos at agora. Assim sendo, antes da funo main() temos:
30

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

catClientes - catlogo de clientes que guarda os clientes do ficheiro clientes.txt;


catProds catlogo de produtos que guarda os produtos do ficheiro produtos.txt;
faturacaoGlobal referencia todos os produtos e guarda informao sobre a faturao
mensal de cada produto e a faturao do ano todo;
filiais array de comprimento 4, cuja posio de ndice 0 guarda informao relativa a
todas as compras de todas as filiais. As posies 1, 2 e 3 do array de filiais guardam
informao relativa s filiais 1, 2 e 3, respetivamente.
fichCarregados varivel do tipo bool que indica se os ficheiros de dados esto
carregados.
Ao declararmos as variveis acima apresentadas como static, fora de qualquer funo
do ficheiro main.c, garantimos que estas so globais a main.c e ao mesmo tempo
privadas aos restantes mdulos, ficando assegurado o encapsulamento dos dados.

Estruturao do programa principal


Ecr inicial
Quando o programa principal comea a ser executado apresentado um splash screen e
a indicao prima enter para continuar.
Interpretador de comandos
Mal o utilizador prima ENTER no ecr inicial, invocada a funo interpretador(),
responsvel por apresentar o menu com as opes do programa GereVendas, ler o input
do utilizador e invocar a funo interpreta() para o interpretar. O menu no mais do
que uma enumerao dos vrios comandos que o utilizador tem sua escolha. Para
selecionar uma opo, o utilizador s precisa de ver qual o seu nmero da mesma no
menu e introduzi-lo.
Tal como j foi referido, aps ser introduzida uma opo, esta passada para funo
interpreta(). Esta funo comea por avanar os espaos que o utilizador possa ter
introduzido no incio da linha, at encontrar um carater que no seja um espao:
Se o 1 carater que no um espao for o \0, o utilizador introduziu uma linha
em branco e nesse caso regressamos funo interpretador() para que seja
apresentado novamente o menu e lida uma nova opo;
Se o 1 carater que no um espao for diferente de \0, chamada a funo
atoi() para converter a linha, a partir desse carater, para um valor inteiro:
o Se o resultado da converso for menor ou igual a 0 ou maior que 12, a
opo invlida e apresentada uma mensagem de erro;
o Se a opo fizer parte do menu, mas corresponder a uma query e o
31

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

utilizador no tiver os ficheiros carregados, tambm apresentada uma


mensagem de erro;
o Caso contrrio, a opo vlida e portanto executada;
Invocao da funo correspondente a uma opo
Para evitar utilizar um bloco grande de if () else if () else, optamos pela
utilizao de uma dispatch table, i.e.: um array de apontadores para funes que na
posio de ndice i tem o endereo da funo correspondente opo i. No incio do
ficheiro main.c temos ento:

Query 1: Leitura dos ficheiros


Quando o utilizador seleciona a opo Ler ficheiros:
1. feita a verificao do valor da flag fichCarregados e se esta tiver o valor lgico
TRUE, chamada a funo auxiliar apagaEstruturas(), responsvel por invocar as
funes da APIs dos catlogos, faturao global e filial que libertam a memria
alocada para as estruturas carregadas anteriormente. Antes de terminar, a funo
apagaEstruturas() coloca a flag fichCarregados com o valor lgico FALSE;
2. invocada a funo auxiliar criaEstruturas() que por sua vez invoca as funes
criaCatProds(), criaCatClientes(), criaFaturacaoGlobal() e criaFilial() (para
cada filial do array de filiais). Se alguma alocao falhar, a funo criaEstruturas()
devolve ERRO_MEM (uma macro que corresponde ao valor -1 e permite que as
vrias funes auxiliares indicar falhas de alocao);
3. chamada a funo auxiliar leFicheiros(), responsvel por dar a escolher ao
utilizador se pretende, para cada um dos ficheiros (clientes, produtos e vendas),
introduzir o caminho do mesmo ou premir ENTER para carregar o ficheiro por
omisso. Para cada um dos ficheiros, existe tambm uma funo auxiliar,
responsvel pela leitura e processamento do mesmo e pela invocao das funes de
insero nas estruturas de dados adequadas. No caso dos ficheiros de produtos e de
clientes, assume-se que estes esto sintaticamente corretos, pelo que no feita
qualquer validao. J no caso do ficheiro de vendas, os dados de cada linha
podero ser invlidos, pelo que cada linha passada para a funo auxiliar
insereSeValida() que s regista os dados de uma venda na faturao global e nas
filiais se estes forem vlidos;
Nota: como a faturao global deve referenciar todos os produtos, ao lermos o ficheiro
produtos.txt, inserimos uma cpia de cada cdigo de produto no catlogo de produtos e
outra na faturao global.
Os ficheiros por omisso esto definidos nas seguintes macros:

32

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

33

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

Navegao
Antes de apresentarmos a query 2, convm primeiro referir como navegamos na
quantidade considervel de Strings produzida por vrias queries (nomeadamente a
query 2).
Como j foi visto anteriormente, a API de LStrings j tem todas as funes necessrias
para navegar numa lista de Strings e obter pginas da mesma. Assim sendo, no ficheiro
main.c bastou definir uma funo navega() que recebe uma LStrings (a que
chamaremos lStr).
Se lStr for uma lista vazia, apresentada a mensagem Lista vazia e no feito
qualquer tipo de navegao.
Se lStr tiver pelo menos uma String, chamada a funo auxiliar
imprimeInformacaoLStrings() para imprimir no ecr o nmero de entradas, o nmero
total de pginas e o nmero de entradas por pgina de lStr. Em seguida entramos no
ciclo que:
1. Limpa o ecr;
2. Invoca a funo obterPag(), para obter a pgina atual de lStr;
3. Passa a pgina obtida para a funo auxiliar apresentaPag() que vai invocar
ciclicamente obterLinha(), seguida de puts() para apresentar cada uma das
linhas da pgina recebida;
4. Apresenta o menu da navegao:

Nota: <total> indica o local onde impresso o nmero total de pginas da


LStrings.
5. L um inteiro com a opo do utilizador;
a. Se a opo for invlida, apresenta uma mensagem de erro e regressa ao
ponto nmero 1. ;
b. Se a opo for vlida e diferente de 7, executa-a e regressa ao ponto
nmero 1;
c. Se a opo for igual a 7 (Sair), sai da navegao;
A invocao das opes contidas no intervalo [1,6] feita atravs de uma dispatch
table, definida no incio do ficheiro main.c como:

34

MIEI - UMinho 2016 LI3 TP de C

Joo Martins, Joo Pereira, Manel Castro

pagAnt(), proxPag(), primPag() e ultimaPag() so funes da API de


LStrings;
perguntaPag() e imprimeInformacaoLStrings() so funes auxiliares
definidas no ficheiro main.c, uma vez que realizam IO.
o perguntaPag() pergunta ao utilizador para que pgina pretende ir e se
essa pgina for vlida, invoca a funo irParaPag() da API de LStrings;
o imprimeInformacaoLStrings(), apresenta novamente as informaes
que so impressas antes da 1 pgina de uma LStrings no vazia ser
apresentada;

Query 2: Lista e n total de produtos comeados por uma letra


Como temos a funo prodsPorLetra() na API do catlogo de produtos, ao
implementarmos a funo query2() no ficheiro main.c s precisamos de pedir ao
utilizador para introduzir uma letra, validar a letra introduzida e, se esta for vlida,
invocar prodsPorLetra() para obter uma LStrings com os cdigos dos produtos
comeados pela letra que o utilizador escolheu. A LStrings obtida ento passada para
a funo navega(), permitindo que o utilizador navegue no resultado.
Query3: Quantidade vendida e faturao total de um produto num
dado ms
A funo query3() l o cdigo de um produto e um ms, testa a validade de cada um
dos valores lidos e, se estes estiverem corretos, invoca a funo obterFatProdMes() da
API da faturao global, para obter a referncia da estrutura com as vrias informaes
sobre faturao do produto escolhido, no ms dado. A partir daqui basta perguntar ao
utilizador se pretende resultados globais ou por filial e, consoante a resposta, invocar as
funes da API da faturao global que permitem, a partir de um elemento do tipo
abstrato de dados FatProdMes, obter os resultados que so pedidos.
Query4: Lista de produtos no comprados globalmente ou por filial

35

Potrebbero piacerti anche