Você está na página 1de 46

Engenharia Electrotcnica e de Computadores

Trabalho prtico em linguagem C


PROGRAMAO I
07-07-2013

Instituto Politcnico do Cvado e do Ave Rogrio Lopes 5475 & Joo Figueiredo 5424

Relatrio do trabalho prtico

Relatrio do trabalho prtico

ndice
ndice .............................................................................................................................. 1 1Introduo .............................................................................................................. 2 1.1 1.2 Objectivos realizados ...................................... Erro! Marcador no definido. Apreciao final............................................................................................ 42

2- Descrio tcnica .9 2.1- Aplicao A ..9 2.2- Aplicao B..17 2.3- Aplicao C..26 3- Concluses 41 3.1- Objectivos realizados 41 Bibliografia..42

Rogrio Lopes & Joo Figueiredo

Relatrio do trabalho prtico

1- Introduo
Uma lista ligada trata-se de um estrutura de dados dinmica composta por diversos ns, tambm designados nodos, que se encontram ligados entre si atravs de apontadores. Os ns de uma lista ligada podero conter um registo composto de um ou mais tipos de dados assim como um apontador ou endereo de memria para o registo imediato que a sucede, no sendo por isso totalmente adjacentes na memria atribuda (RAM). A lista ligada simples uma estrutura de dados linear e dinmica. Composta por diversos ns, ligados entre si sequencialmente. Sendo assim, esta estrutura permitir representar um conjunto de dados de modo a preservar a relao de ordem linear entre eles. Ou seja, o conjunto de ns da lista ligada pode ser expresso pela seguinte equao: L = { x1, x2, x3, ..., xn}, onde xk precedido por xk-1 e seguido de xk+1, para 1<k<n. Posto isto, se n=0 ento a lista ser vazia.

Fig. 1- Modelo de uma lista ligada simples Tudo isto permite inferir que numa lista ligada simples cada n est ligado ao seu sucessor e a nenhum outro elemento. Para a sua manipulao existem dois gneros distintos de variveis sendo uma delas, relacionada com apontadores que so variveis cujos valores apontam para outras variveis e, por outro lado, temos as variveis objecto as quais so apontadas. No caso de uma lista ligada simples, cada n est ligado apenas ao seu sucessor. Existem diversos tipos de apontador cuja definio a seguinte: TIPO

Rogrio Lopes & Joo Figueiredo

Relatrio do trabalho prtico

tipo de apontador = ^identificador de tipo Neste caso, o identificador de tipo refere-se ao tipo da varivel do objecto correspondente sendo que uma varivel apontador representar um endereo que indica a localizao de uma varivel objecto cujo gnero especificado pelo elemento que identifica o seu gnero. A implementao de listas ligadas simples promovem algumas vantagens tais como a possibilidade de insero ou remoo de um elemento na lista sem que estas operaes no impliquem a mudana de lugar de outros elementos. Por outro lado no necessrio definir ao criar-se a lista o nmero mximo de elementos que esta poder ter, sendo por isso possvel alocar elementos de memria de forma dinmica apenas no nmero de ns necessrios. No entanto existem desvantagens na implementao de listas ligadas simples, uma vez que a sua manipulao envolve mais riscos na medida em que a ligao entre os diversos elementos que compe a lista for mal feita, todo o trabalho poder ser perdido. Outro aspecto reside no facto de que para aceder a um elemento de uma posio, a lista dever percorrer todos os elementos anteriores at chegar ao pretendido. Por sua vez, as listas duplamente ligadas permitem ser percorridas em dois sentidos, uma vez que cada n possui dois apontadores em que um corresponde ao sucessor e outro ao anterior. Existe maior facilidade no controlo da lista, assim com maior fiabilidade e menor risco de perdas na sua concepo em relao s listas ligadas simples. As rvores binrias so estruturas de dados que se caracteriza por possuir um elemento distinto, a raiz, com dois apontadores para as duas estruturas diferentes, sendo estas denominadas sub rvore esquerda e sub rvore direita. Por outro lado, a rvore binria poder no ter qualquer elemento. Nesta estrutura de dados utiliza-se a recursividade, utilizada nas mais diversas operaes sobre as rvores binrias. O gnero de rvore binria mais simples a de busca. O conceito de recursividade permite implementar algoritmos que simplificam a questo principal a solucionar, tornando essa questo principal em questes sucessivas mas mais simples com a

Rogrio Lopes & Joo Figueiredo

Relatrio do trabalho prtico

mesma estrutura inicial. Em suma, a recursividade permite decompor uma questo complexa em diversas questes mais simples que sero exactamente do mesmo gnero da primeira at que a soluo seja conhecida de forma mais bvia. O trabalho prtico proposto visa na colocao em prtica de conceitos leccionados nas aulas sobre a linguagem de programao C, assim como algum trabalho de pesquisa para possibilitar a realizao do mesmo. De uma forma mais concreta, o trabalho proposto consiste no desenvolvimento de trs aplicaes distintas, as quais devero possuir um menu de operao para o utilizador de forma a invocar as funcionalidades definidas sendo que alm disto o objectivo tambm incide no armazenamento e disponibilidade de carregar toda a informao atravs de ficheiros. A primeira aplicao consiste no desenvolvimento de um programa que permita a gesto de um arquivo de exames de diagnstico mdico, cuja estrutura de dados incide numa lista ligada simples. Em suma, trata se de uma clinica mdica, que tem a necessidade de gerir exames de diagnstico feitos a cada doente, dispondo para isso de mltiplos servios, departamentos e especialidades. Ser, portanto, necessrio arquivar um exame realizado numa determinada data por um tcnico. Neste caso ser ento importante realizar uma consulta aos exames efectuados num perodo de tempo, fazer uma consulta aos exames de um doente especfico e, por fim, arquivar em formato digital o exame realizado. Com a segunda aplicao pretende-se gerir um simpsio de medicamentos genricos atravs de uma lista duplamente ligada. O problema enunciado foca-se numa empresa farmacutica que pretende desenvolver um simpsio de medicamentos genricos de modo a que este seja fornecido a mdicos de diferentes especialidades. O simpsio conter toda a informao considerada relevante por parte do mdico. Os medicamentos estaro agrupados por laboratrios. A aplicao dever possibilitar os registos quer de um novo medicamento quer de um novo princpio activo, assim como consultar mltiplos critrios e remoo de medicamentos.

Rogrio Lopes & Joo Figueiredo

Relatrio do trabalho prtico

Por fim, a ltima aplicao dever permitir a gesto de provas desportivas atravs de uma rvore binria de procura, ou seja, uma associao pretende adquirir uma aplicao capaz de efectuar a gesto de uma prova desportiva tal como uma corrida de orientao em que cada atleta identificado com um nmero no seu peito, pertencendo a um dado clube e escalo consoante a sua idade. Ser, portanto, necessrio registar o tempo de partida e chegada de cada atleta, sendo que o seu percurso determinado pelo escalo ao qual o atleta pertence. Finda a prova, ser necessrio listar todos os atletas que a terminaram, consultar informao de um determinado atleta, gerando uma lista ligada por tempo de prova. Por fim, dever ainda ser possvel inscrever uma atleta na prova e gerar uma lista geral dos atletas por tipo de prova ou escalo sendo a ordenao feita pelo nmero do atleta.

Rogrio Lopes & Joo Figueiredo

Relatrio do trabalho prtico

Rogrio Lopes & Joo Figueiredo

Relatrio do trabalho prtico

2- Descrio tcnica
Nesta seco ser descrito todo o cdigo implementado, assim como todo o fundamento terico necessrio melhor compreenso possvel do mesmo. Todos os procedimentos sero descritos e s, posteriormente a cada explicao apresentarse-o os excertos de cdigo implementado para cada funo.

2.1- Aplicao A
Numa fase inicial criou se a estrutura da lista ligada, efectuando a enumerao, das bibliotecas necessrias assim como todas as variveis contidas na mesma. Esta lista foi denominada exame. #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct registo { int cod,numut,dia,mes,ano,idmedico; char exame[15]; char nomeutente[50]; char nomemedico[50]; struct registo *seguinte; }Exame; De seguida construiu-se o menu atravs da utilizao do comando printf para a escrita na consola dos vrios elementos constituintes do menu pretendido para a aplicao. de frisar, tambm, a utilizao do system("cls") para limpar a linha de comandos, ou seja, o que foi redigido anteriormente ao ecr no menu. void menu() { system("cls"); printf("--------------------------------------------\n"); printf("\tSeleccionar opcao:\n");

Rogrio Lopes & Joo Figueiredo

Relatrio do trabalho prtico

printf("\t1-Novo Exame\n"); printf("\t2-Pesquisar Exame por Data\n"); printf("\t3-Pesquisar Exame por Nome de Utente\n"); printf("\t4-Lista de Exames\n"); printf("\t5-Guardar Exames todos\n"); printf("\t0-Sair\n\n"); printf("---------------------------------------------\n"); } Definiu-se, depois, a funo para inserir os exames na lista ligada simples com os dados iguais ao typedef do registo igualando, assim, as variveis do typedef s do novo apontador de modo a que seja permitido gravar os dados na mesma, apontando sempre uma nova lista para a posio seguinte.

Exame * InserirExame(Exame *apt, int cod, char texame[15], char nome[50], int numutente, int da, int ms, int an, int idmed, char nmed[50]) { Exame *novo=(Exame *) malloc(sizeof(Exame)); novo->ano = an; novo->cod = cod; novo->dia = da; novo->mes = ms; strcpy(novo->nomeutente, nome); strcpy(novo->nomemedico, nmed); novo->numut = numutente; novo->idmedico = idmed; strcpy(novo->exame,texame); novo->seguinte=apt; return(novo); }

Rogrio Lopes & Joo Figueiredo

10

Relatrio do trabalho prtico

Para criar uma funo que permitisse pesquisar um utente na lista, criou-se um ciclo if inserido num ciclo while. Segue-se a funo para listar os exames, assim como dizer quantos foram encontrados. Posto isto, a funo permite percorrer toda a lista ligada assim como caso uma clula contivesse informao design-la, caso contrrio ao verificar se as clulas so preenchidas efectua uma operao de incremento para localizar uma clula com informao.

void Pesquisar_Utente(Exame *apt, char nm[50]) { int d=0; while(apt!=NULL) { if(strcmp(nm, apt->nomeutente)==0) {

printf("Encontraram-se os seguintes exames com o nome %s\n\n", nm); printf("Codigo de Exame: %d\n", apt->cod); printf("nNumero de Utente: %d\n", apt->numut); printf("Tipo de Exame: %s\n", apt->exame); printf("Data:%d/%d/%d\n", apt->dia, apt->mes, apt->ano); printf("Nome do Medico: %s\n", apt->nomemedico); printf("Numero do Medico: %d\n\n", apt->idmedico); apt=apt->seguinte; d++; } } printf("Encontraram-se %d exames.\n", d); system("pause"); }

Rogrio Lopes & Joo Figueiredo

11

Relatrio do trabalho prtico

Segue-se a funo para listar os exames, assim como dizer quantos foram encontrados. Desta, feita efectuou-se um ciclo while que enquanto o apontador tinha valor diferente de zero, so impressas as frases correspondentes ao menu a mostrar na consola para o utilizador. De salientar, tambm, a utilizao de uma funo de incremento. void listar(Exame *apt) {

int c=0; while(apt!=NULL) { printf("--------------------------------------------------------\n");

printf("Codigo de Exame: %d\n", apt->cod); printf("Nome de Utente: %s \n", apt->nomeutente); printf("Numero de Utente: %d \n", apt->numut); printf("Tipo de Exame: %s \n", apt->exame); printf("Data:%d/%d/%d \n", apt->dia, apt->mes,apt->ano); printf("Nome do Medico: %s\n", apt->nomemedico); printf("Numero do Medico: %d\n\n", apt->idmedico); printf("--------------------------------------------------------\n"); apt=apt->seguinte; c++; } printf("Foram encontrado(s) %d Exame(s).\n", c); system("pause"); } A funo implementada de seguida visa a possibilidade de guardar todos os exames e apresentar os resultados em formato digital atravs de um ficheiro no fromato .txt. Implementou-se um ciclo while assim como o fprintf de modo a gerar o ficheiro pretendido assim no qual se apresentaram todos os campos obtidos.

Rogrio Lopes & Joo Figueiredo

12

Relatrio do trabalho prtico

void guardartodos(Exame*apt) { FILE*fp; int i=1; fp=fopen("Examestodos.txt","w"); while(apt!=NULL) { fprintf(fp,"Utente: %s \n ",apt->nomeutente); fprintf(fp,"-----------------------------------\nExame:%d\nData: %d-%d-%d \nTipo de Exame:%s \nTecnico:%s \n--------------------------------\n \n\n ",i=i++,apt->dia,apt>mes,apt->ano,apt->exame,apt->nomemedico); apt=apt->seguinte; }

} A funo seguinte permite a leitura dos registos do ficheiro de texto, sendo esta totalmente funcional tal como o cdigo o demonstra Exame *carregar(Exame *apt) { FILE * fp; int cd, nu, idt, d, m, a; char n[50], tp[15], nt[50]; fp = fopen("Examestodos.txt", "r"); if(fp==NULL) { printf("Impossivel carregar dados guardados\n"); return(NULL); system("pause"); } else {

Rogrio Lopes & Joo Figueiredo

13

Relatrio do trabalho prtico

do { fscanf(fp,"%d\n",&cd); fscanf(fp,"%s\n",n); fscanf(fp,"%d\n",&nu); fscanf(fp,"%s\n",tp); fscanf(fp,"%s\n",nt); fscanf(fp,"%d\n",&idt); fscanf(fp,"%d\n",&d); fscanf(fp,"%d\n",&m); fscanf(fp,"%d\n",&a); apt=InserirExame(apt, cd, tp, n, nu, d, m, a, idt, nt);

}while(feof(fp)==0); } fclose(fp); return(apt); }

Por fim, efectuou-se a funo principal, main. Aps a declarao de todas as variveis, criou-se um menu atravs de um operador switch de modo a gerar um menu com uma estrutura case para gerar um menu principal assim como acesso aos menus secundrios. int main() { int cod,numutente,da,ms,an,idmed,op,d,m,a; char texame[15], nome[50], nmed[50], nomi[50]; Exame * lista = NULL; lista = carregar(lista); menu(); scanf("%d", &op); fflush(stdin);
Rogrio Lopes & Joo Figueiredo 14

Relatrio do trabalho prtico

while(op!=0) {switch(op) { case 1: system("cls"); printf("Insira o codigo:\n"); scanf("%d", &cod); fflush(stdin); printf("Insira o Nome do Utente:\n"); gets(nome); fflush(stdin); printf("Insira o Numero de Utente\n"); scanf("%d", &numutente); fflush(stdin); printf("Insira o Tipo de Exame\n"); gets(texame); fflush(stdin); printf("Insira o Dia\n"); scanf("%d", &da); fflush(stdin); printf("Insira o Mes\n"); scanf("%d", &ms); fflush(stdin); printf("Insira o Ano\n"); scanf("%d", &an); fflush(stdin); printf("Insira o Numero do Medico\n"); scanf("%d", &idmed); fflush(stdin); printf("Insira o Nome do Medico\n"); gets(nmed); fflush(stdin);
Rogrio Lopes & Joo Figueiredo 15

Relatrio do trabalho prtico

lista = InserirExame(lista,cod, texame, nome, numutente, da, ms, an, idmed, nmed); break; case 2: system("cls"); printf("Insira a data:\n");

printf("Dia:\n"); scanf("%d", &d); fflush(stdin); printf("Mes:\n"); scanf("%d", &m); fflush(stdin); printf("Ano:\n"); scanf("%d", &a); fflush(stdin); Pesquisar_Data(lista, d, m, a); break; case 3: system("cls"); printf("Insira o nome do utente:\n"); gets(nomi); fflush(stdin); Pesquisar_Doente(lista, nomi); break; case 4: system("cls"); listar(lista); break; case 5: system("cls"); guardar(lista); break;
Rogrio Lopes & Joo Figueiredo 16

Relatrio do trabalho prtico

menu(); scanf("%d", &op); fflush(stdin); }

//system("pause"); return 0; }

2.2 Aplicao B
A segunda aplicao consiste na gesto de um simpsio de medicamentos genricos atravs de uma lista duplamente ligada. Aps a incluso das bibliotecas necessrias definiu-se a estrutura da lista ligada referente aos medicamentos atravs do typedef struct seguida da declarao das variveis constituintes desta lista. #include <stdio.h> #include <stdlib.h> #include <string.h>

typedef struct Medicamento { int idmed; char nmed[50]; char nlab[50]; char cp[100]; char efsecund[100]; char indic[100]; char psg[30]; char pact[30]; struct Medicamento *seguinte; struct Medicamento *anterior; }MEDICAMENTO; A implementao que se segue, tem em vista a insero de um novo medicamento, verificando em que posio fica gravado, ou seja, fica na clula

Rogrio Lopes & Joo Figueiredo

17

Relatrio do trabalho prtico

anterior se estiver vazia, caso contrrio fica na seguinte sendo que por defeito grava sempre na anterior. MEDICAMENTO * InserirMed(MEDICAMENTO * apt, int idm, char nome[50], char nomel[50], char comp[100],char pa[30], char efs[100], char ind[100], char pos[30]) { //insercao de um novo medicamento MEDICAMENTO * novo = (MEDICAMENTO *)malloc(sizeof(MEDICAMENTO)); strcpy(novo->cp, comp); strcpy(novo->efsecund, efs); novo->idmed = idm; strcpy(novo->indic, ind); strcpy(novo->nlab, nomel); strcpy(novo->nmed, nome); strcpy(novo->psg, pos); strcpy(novo->pact,pa); novo->seguinte = apt; novo->anterior = NULL; if(apt!=NULL) { apt->anterior = novo; } return (novo); } De seguida, implementou-se uma funo que permite pesquisar um medicamento de modo a confirmar se o nome do mesmo est ou no inserido ou, por outro lado, indicar o nome do medicamento a remover. int existe(MEDICAMENTO * apt, char n[50]) { //Confirma se existe ou nao o nome inserido ou o nome a remover while(apt!=NULL) { if((strcmp(apt->nmed, n))==0) { return (1); } apt=apt->seguinte; } return (0); } De seguida, implementou-se uma funo que permite efectuar a listagem de todos os medicamentos inseridos, apresentando no final o nmero de medicamentos encontrados na lista.

Rogrio Lopes & Joo Figueiredo

18

Relatrio do trabalho prtico

void Listar_todos(MEDICAMENTO *apt) { //lista todos os medicamentos inseridos int d=0; while(apt!=NULL) { printf("Numero medicamento: %d\n", apt->idmed); printf("Nome: %s\n", apt->nmed); printf("Nome do laboratorio: %s\n", apt->nlab); printf("Composicao: %s\n", apt->cp); printf("Efeitos secundarios: %s\n", apt->efsecund); printf("Indicacoes: %s\n", apt->indic); printf("Principio Activo: %s\n", apt->pact); printf("Posologia: %s\n\n", apt->psg); d++; apt=apt->seguinte; } printf("Foram encontrados %d medicamentos\n\n", d); system("pause"); } Segue-se o procedimento de pesquisa por nome na lista ligada. Para tal implementou-se um ciclo while com um ciclo else-if interno onde era impresso o nome de medicamento, nome do laboratrio, composio, principio activo, efeitos secundrios, indicaes e posologia. A impresso final, indicado se foram ou no encontrados medicamentos com o nome enunciado. void Procurar_Nome(MEDICAMENTO *apt, char n[50]) { //pesquisa por nome de medicamento int c=0; while((apt!=NULL)&&(c==0)) { if(strcmp(apt->nmed, n)==0) { printf("Numero medicamento: %d\n", apt->idmed); printf("Nome do laboratorio: %s\n", apt->nlab); printf("Composicao: %s\n", apt->cp); printf("Principio activo: %s\n", apt->pact); printf("Efeitos secundarios: %s\n", apt->efsecund); printf("Indicacoes: %s\n", apt->indic); printf("Posologia: %s\n\n", apt->psg); system("pause"); c=1; }

Rogrio Lopes & Joo Figueiredo

19

Relatrio do trabalho prtico

Else { apt=apt->seguinte; } } if(c==0) { printf("Nao foram encontrados medicamentos com o nome %s\n", n); system("pause"); } } A operao seguinte consiste na procura atravs do nome do laboratrio, ou seja, atravs de um ciclo if-else interno a um ciclo while, apresentando no final na consola quantos medicamentos foram encontrados nas condies referidas. void Procurar_Laboratorio(MEDICAMENTO *apt, char nl[50]) { // pesquisa por nome do laboratorio int a=0; while(apt!=NULL) { if((strcmp(apt->nlab, nl))==0) { printf("Nome: %s\n", apt->nmed); printf("Numero medicamento: %d\n", apt->idmed); printf("Composicao: %s\n", apt->cp); printf("Principio activo: %s\n", apt->pact); printf("Efeitos secundarios: %s\n", apt->efsecund); printf("Indicacoes: %s\n", apt->indic); printf("Posologia: %s\n\n", apt->psg); apt=apt->seguinte; a++; } else { apt=apt->seguinte; } } printf("Foram encontrados %d medicamentos.\n", a); system("pause"); } Segue-se a pesquisa por princpio activo na lista duplamente ligada com um processo semelhante ao anterior em termos de funes aplicadas. No final so

Rogrio Lopes & Joo Figueiredo

20

Relatrio do trabalho prtico

disponibilizados ao utilizador atravs da consola o nmero de medicamentos encontrados segundo o princpio activo pesquisado. Procurar_principio_activo(MEDICAMENTO *apt, char pa[30]) { // pesquisa por principio activo int c=0; while(apt!=NULL) { if((strcmp(apt->pact, pa))==0) { printf("Nome: %s\n", apt->nmed); printf("Numero medicamento: %d\n", apt->idmed); printf("Nome do laboratorio: %s\n", apt->nlab); printf("Composicao: %s\n", apt->cp); printf("Efeitos secundarios: %s\n", apt->efsecund); printf("Indicacoes: %s\n", apt->indic); printf("Posologia: %s\n\n", apt->psg); apt=apt->seguinte; c++; } else { apt=apt->seguinte; } } printf("Foram encontrados %d medicamentos\n\n", c); system("pause"); } A funo que permite guardar os dados em formato digital em formato. txt, atravs de um ciclo while, demonstrando nesse documento todos os dados acerca de um dado medicamento previamente inserido pelo utilizador. int guardar(MEDICAMENTO * apt) {FILE * fp; fp = fopen("Medicamentos.txt","w"); while(apt!=NULL) { fprintf(fp,"--------------------------------\n"); fprintf(fp,"Numero Medicamento:%d\n",apt->idmed); fprintf(fp,"Nome Medicamento:%s\n",apt->nmed); fprintf(fp,"Nome laboratorio:%s\n",apt->nlab); fprintf(fp,"Composicao:%s\n",apt->cp); fprintf(fp,"Efeitos secundarios:%s\n",apt->efsecund); fprintf(fp,"Indicadores%s\n",apt->indic);

Rogrio Lopes & Joo Figueiredo

21

Relatrio do trabalho prtico

fprintf(fp,"Posologia:%s\n",apt->psg); fprintf(fp,"Pactivo:%s\n",apt->pact); fprintf(fp,"----------------------------------\n"); apt=apt->seguinte; } fclose(fp); return(0); } A funo que se segue tem em vista a remoo de um dado medicamento atravs da implementao de um ciclo else if dentro de um ciclo while. void Remover(MEDICAMENTO ** AptInicio, MEDICAMENTO ** AptFim, char n[50]) { MEDICAMENTO * aux=*AptInicio; while((aux!=NULL)&&((strcmp(aux->nmed, n))!=0)) aux=aux->seguinte; if ((aux!=NULL)&&(aux->anterior==NULL)) { *AptInicio = aux->seguinte; free(aux); } else if ((aux!=NULL)&&(aux->seguinte==NULL)) { *AptFim = aux->anterior; free(aux); } else if ((aux!=NULL)&&(aux->seguinte==NULL)&&(aux->anterior==NULL)) { *AptInicio = NULL; *AptFim = NULL; free(aux); } else if (aux!=NULL) {aux->anterior->seguinte=aux->seguinte; aux->seguinte->anterior = aux->anterior; free(aux); } } A funo de leitura, totalmente funcional tal como na primeira aplicao foi estruturada tal como o excerto de cdigo seguinte o demonstra. MEDICAMENTO *carregar(MEDICAMENTO *apt) { FILE * fp; int idm; char nome[50], nomel[50], comp[100], efs[100], ind[100], pos[30], pa[30]; fp = fopen("Medicamentos.txt", "r");

Rogrio Lopes & Joo Figueiredo

22

Relatrio do trabalho prtico

if(fp==NULL) { printf("Impossivel carregar dados guardados\n"); return(NULL); system("pause"); } else { do { fscanf(fp,"%d\n",&idm); fscanf(fp,"%s\n",nome); fscanf(fp,"%s\n",nomel); fscanf(fp,"%s\n",comp); fscanf(fp,"%s\n",efs); fscanf(fp,"%s\n",ind); fscanf(fp,"%s\n",pos); fscanf(fp,"%s\n",pa); apt=InserirMed(apt, idm, nome, nomel, pa, comp, efs, ind, pos); }while(feof(fp)==0); } fclose(fp); return(apt); } Segue-se a definio do menu no qual se implementaram diversos printf e um system(cls) para limpar os dados inseridos anteriormente na consola. void menu() { system("cls"); printf("------------------------------------\n"); printf("\tSeleccione a sua Opcao:\n\n"); printf("\t1-Novo Medicamento\n"); printf("\t2-Procurar por Nome\n"); printf("\t3-Procurar por Laboratorio\n"); printf("\t4-Procurar por Principio Activo\n"); printf("\t5-Listar todos\n"); printf("\t6-Retirar Medicamento\n"); printf("\t7-Guardar Medicamentos\n"); printf("\t0-Sair\n\n"); printf("-------------------------------------"); }

Rogrio Lopes & Joo Figueiredo

23

Relatrio do trabalho prtico

Para a estrutura da funo principal, main, declarando todas as variveis e criando um menu atravs de um operador switch para gerar um menu atravs de uma estrutura case para o menu principal assim como para o acesso aos sub menus. int main() { int idm, op, op2; char nome[50], nomel[50], comp[100], efs[100], ind[100], pos[30], nomepac[50], pa[30]; MEDICAMENTO *SInicio = NULL; MEDICAMENTO *SFim = NULL; SInicio = carregar(SInicio); menu(); scanf("%d", &op); while(op!=0) { switch(op) { case 1: system("cls"); printf("Insira o codigo de medicamento:\n"); scanf("%d", &idm); fflush(stdin); system("cls"); printf("Nomenclatura:\n"); scanf("%s", nome); fflush(stdin); system("cls"); printf("Insira o nome do laboratorio:\n"); scanf("%s", nomel); fflush(stdin); system("cls"); printf("Insira a composicao:\n"); scanf("%s", comp); fflush(stdin); system("cls"); printf("Insira o principio activo:\n"); scanf("%s", pa); fflush(stdin); system("cls"); printf("Insira as efeitos secundarios:\n"); scanf("%s", efs); fflush(stdin); system("cls"); printf("Insira as indicacoes:\n"); scanf("%s", ind); fflush(stdin);
Rogrio Lopes & Joo Figueiredo 24

Relatrio do trabalho prtico

system("cls"); printf("Insira a posologia:\n"); scanf("%s", pos); fflush(stdin); system("cls"); if(existe(SInicio, nome)==1) { printf("O medicamento ja esta inserido no Simposium"); system("pause"); } else { SInicio = InserirMed(SInicio, idm, nome, nomel, comp, pa, efs, ind, pos); printf("Medicamento inserido com sucesso!\n"); system("pause"); } break; case 2: system("cls"); printf("Insira o nome do medicamento:\n"); scanf("%s", nome); Procurar_Nome(SInicio, nome); break; case 3: system("cls"); printf("Insira o nome do laboratorio:\n"); scanf("%s", nomel); Procurar_Laboratorio(SInicio, nomel); break; case 4: system("cls"); printf("Insira o principio activo:\n"); scanf("%s", nomepac); Procurar_principio_activo(SInicio, nomepac); break; case 5: system("cls"); Listar_todos(SInicio); break; case 6: system("cls"); printf("Insira o nome do medicamento:\n");

Rogrio Lopes & Joo Figueiredo

25

Relatrio do trabalho prtico

scanf("%s", nome); fflush(stdin); if(existe(SInicio, nome)==1) { Remover(&SInicio, &SFim, nome); printf("Medicamento removido com sucesso!\n\n"); system("pause"); } else { printf("Nao existe nenhum medicamentos com o esse nome\n\n"); system("pause"); } break; case 7: guardar(SInicio); break; } menu(); scanf("%d", &op); }

return 0; }

2.3 Aplicao C
A aplicao final consiste, atravs de um rvore binria de procura, efectuar a gesto de uma prova desportiva, mais concretamente, uma corrida de orientao. Este gnero de prova caracterizado pelos seguintes elementos: - A identificao de cada atleta feita atravs de um nmero exibido no peitoral sendo que cada atleta pertence a um clube e a um determinado escalo de acordo com a sua idade. Ser, portanto, necessrio registar o tempo de partida e chegada de cada atleta. No fim da prova ser necessrio listar todos os atletas que concluram a prova, assim como a consulta de toda a informao de um dado atleta. O tempo de prova dever ser gerado atravs de uma lista ordenada, assim como dever ser possvel a inscrio de um atleta na prova, gerando-se posteriormente uma lista geral dos atletas pelo seu escalo, ordenada pelo nmero do atleta tal como referido anteriormente. Infelizmente no foi possvel completar a mesma devido ao facto de dentro de diversas tentativas se dar uma enorme persistncia de erros o que

Rogrio Lopes & Joo Figueiredo

26

Relatrio do trabalho prtico

impossibilitou a sua concluso total, tendo apenas algumas seces funcionais descritas de seguida. Em primeiro lugar definiram-se as bibliotecas a utilizar para efectuar esta parte do trabalho prtico proposto. #include <stdio.h> #include <stdlib.h> #include <string.h>

De seguida, efectuou-se a definio da estrutura do registo, definindo-se tambm todas as variveis a utilizar.

typedef struct AB { int numero, idade; char nome[50], clube[30]; int hc, mc, sc, hp, mp, sp; struct AB *dir; struct AB *esq; }ATLETA;

Tal como pretendido, cabe agora, a insero de todos os dados relativos a um dado atleta atravs de ciclos If para todas as ramificaes das razes da rvore em questo que tanto poder ir para a direita como para a esquerda. ATLETA*lista=NULL; ATLETA *Inserir(ATLETA *raiz, int n,int id, char no[50], char c[30], int hp, int mp, int sp, int hc, int mc, int sc) {

if(raiz==NULL) { raiz=(ATLETA*)malloc(sizeof(ATLETA));

Rogrio Lopes & Joo Figueiredo

27

Relatrio do trabalho prtico

strcpy(raiz->nome, no); raiz->numero=n; raiz->idade=id; strcpy(raiz->clube, c); raiz->hc=hc; raiz->mc=mc; raiz->sc=sc; raiz->hp=hp; raiz->mp=mp; raiz->sp=sp; raiz->dir=NULL; raiz->esq=NULL; } else { if(n>raiz->numero) { raiz->dir=Inserir(raiz->dir, n, id, no, c, hp, mp, sp, hc, mc, sc); } else { if(n<raiz->numero) { raiz->esq=Inserir(raiz->esq, n, id, no, c, hp, mp, sp, hc, mc, sc); } } } return(raiz);

Segue-se a estrutura que permite a pesquisa de um atleta por nome onde caso seja encontrado um atleta com um nome correspondente ao inserido pelo utilizador sero apresentados todos os dados inerentes ao mesmo, inseridos
Rogrio Lopes & Joo Figueiredo 28

Relatrio do trabalho prtico

anteriormente aquando da inscrio da prova na fase inicial da aplicao descrita anteriormente. Para isso, utilizaram-se ciclos If e Else-If assim como os comandos scanf e printf para guardar os dados e imprimi-los na consola, respectivamente.

void CNome(ATLETA* raiz, char n[50]) { if(raiz==NULL) { printf("Nao existe ninguem com o nome inserido\n"); } else { if(strcmp(raiz->nome,n)==0) { printf("Nome: %s\n", raiz->nome); printf("Numero: %d\n", raiz->numero); printf("Idade: %d\n", raiz->idade); printf("Clube: %s\n", raiz->clube); if((raiz->idade>=1)&&(raiz->idade<=14)){ printf("Escalao: Iniciado\n"); printf("Percurso: A\n\n");} else if((raiz->idade>=15)&&(raiz->idade<=16)){ printf("Escalao: Juvenil\n"); printf("Percurso: B\n\n");} else if((raiz->idade>=17)&&(raiz->idade<=18)){ printf("Escalao: Junior\n"); printf("Percurso: C\n\n");} else{ printf("Escalao: Senior\n"); printf("Percurso: D\n\n");} } else
Rogrio Lopes & Joo Figueiredo 29

Relatrio do trabalho prtico

{ CNome(raiz->dir, n); CNome(raiz->esq, n); } } } Para aferir os atletas que terminaram a prova utilizou-se o seguinte cdigo, cujo excerto poder ser lido abaixo. Atravs de ciclos If e Else-If foi possvel determinar se um dado atleta concluiu ou no a prova quer no ramo esquerdo quer no ramo direito da rvore binria de consulta desenvolvida.

void terminaramprova(ATLETA* raiz) { /* { printf("Nao existem atletas"); if(raiz==NULL)

}*/if(raiz!=NULL) {

if((raiz->hc==0)||(raiz->mc==0)||(raiz->sc==0)){ printf ("n"); } if((raiz->hc>0)||(raiz->mc>0)||(raiz->sc>0)){

printf("Nome: %s\n", raiz->nome); printf("Numero: %d\n", raiz->numero); printf("Idade: %d\n", raiz->idade); printf("Clube: %s\n", raiz->clube); if((raiz->idade>=1)&&(raiz->idade<=14)){

Rogrio Lopes & Joo Figueiredo

30

Relatrio do trabalho prtico

printf("Escalao: Iniciado\n"); printf("Percurso: A\n");} else if((raiz->idade>=15)&&(raiz->idade<=16)){ printf("Escalao: Juvenil\n"); printf("Percurso: B\n");} else if((raiz->idade>=17)&&(raiz->idade<=18)){ printf("Escalao: Junior\n"); printf("Percurso: C\n");} else{ printf("Escalao: Senior\n"); printf("Percurso: D\n");} }

terminaramprova(raiz->dir); terminaramprova(raiz->esq); } }

O menu foi construdo, semelhana das aplicaes anteriores, atravs de vrios comandos printf para apresentar as diversas opes ao utilizador. void menu(void) { system("cls"); printf("Menu Principal:\n\n"); printf("1-Inserir atleta\n"); printf("2-Consultar atleta por nome\n"); printf("3-Listar atletas que terminaram a prova\n"); printf("4-Gravar Registo\n"); printf("5-Listar por Percurso\n"); printf("0-Sair\n\n"); }

Rogrio Lopes & Joo Figueiredo

31

Relatrio do trabalho prtico

Segue-se a gravao em formato digital, mais concretamente num ficheiro de texto. Para isso ser necessrio gravar os diversos dados relativos a um atleta, sendo estes imprimidos num ficheiro de texto que poder ser porttil ao utilizador, sendo bastante til na eventualidade de haver necessidade de impresso de listas detalhadas acerca dos atletas para um arquivo por exemplo. void gravar (int numero,int idade, int hc, int mc, int sc,int hp, int mp, int sp, char nome[50],char clube[30]) { FILE *ficheiro;

ficheiro = fopen ("ProvasDesportivas.txt", "a");

if (ficheiro != NULL) { fprintf (ficheiro, "%d\n", numero); fprintf (ficheiro, "%d\n", idade); fprintf (ficheiro, "%s\n", nome); fprintf (ficheiro, "%s\n", clube); fprintf (ficheiro, "%d\n", hp); fprintf (ficheiro, "%d\n", mp); fprintf (ficheiro, "%d\n", sp); fprintf (ficheiro, "%d\n", hc); fprintf (ficheiro, "%d\n", mc); fprintf (ficheiro, "%d\n", sc);

} fclose (ficheiro); }

Rogrio Lopes & Joo Figueiredo

32

Relatrio do trabalho prtico

A funo que permite a leitura dos dados do atleta apesar de no estar a funcionar poderia, na ptica dos executores do trabalho, ser funcional na medida em que se trata de uma estrutura idntica das outras aplicaes que esto totalmente funcionais pelo que se tornou um pouco imperceptvel o erro. No entanto, ser de todo pertinente apresentar o raciocnio desenvolvido para o efeito.

ATLETA *carregar(ATLETA *lista) { FILE *ficheiro; int n, id, hc, mc, sc, hp, mp, sp; char no[50], c[50];

ficheiro = fopen ("ProvasDesportivas.txt", "r");

if (ficheiro != NULL) { while (!feof (ficheiro)) { fscanf (ficheiro, "%d\n", &n); fscanf (ficheiro, "%d\n", &id); fscanf (ficheiro, "%s\n", no); fscanf (ficheiro, "%s\n", c); fscanf (ficheiro, "%d\n", &hp); fscanf (ficheiro, "%d\n", &mp); fscanf (ficheiro, "%d\n", &sp); fscanf (ficheiro, "%d\n", &hc); fscanf (ficheiro, "%d\n", &mc); fscanf (ficheiro, "%d\n", &sc);

Rogrio Lopes & Joo Figueiredo

33

Relatrio do trabalho prtico

lista = Inserir (lista,n,id, no,c,hp,mp,sp,hc, mc, sc); } fclose (ficheiro); } return(lista); } No que concerne a listagem dos atletas por percurso, dado que este difere de acordo com o escalo que por sua vez difere de acordo com a idade. Estes percursos so denominados A, B, C, D, previamente definidos aquando da introduo de um atleta que efectuou a prova.

void ListarporP(ATLETA *raiz,int p) { if(raiz!=NULL) {

if(p==1){ if((raiz->idade>=1)&&(raiz->idade<=14)){ system("cls"); printf("Escalao: Iniciado\n"); printf("Percurso: A\n"); printf("Nome: %s\n", raiz->nome); printf("Numero: %d\n", raiz->numero); printf("Idade: %d\n", raiz->idade); printf("Clube: %s\n", raiz->clube); printf("Hora de partida: %d-%d-%d\n", raiz->hp, raiz->mp, raiz->sp); printf("Hora de cheagada: %d-%d-%d\n\n", raiz->hc, raiz->mc, raiz->sc); system("pause");}} if(p==2){ if((raiz->idade>=15)&&(raiz->idade<=16)){

Rogrio Lopes & Joo Figueiredo

34

Relatrio do trabalho prtico

system("cls"); printf("Escalao: Juvenil\n"); printf("Percurso: B\n"); printf("Nome: %s\n", raiz->nome); printf("Numero: %d\n", raiz->numero); printf("Idade: %d\n", raiz->idade); printf("Clube: %s\n", raiz->clube); printf("Hora de partida: %d-%d-%d\n", raiz->hp, raiz->mp, raiz->sp); printf("Hora de cheagada: %d-%d-%d\n\n", raiz->hc, raiz->mc, raiz->sc); system("pause");}} if(p==3){ if((raiz->idade>=17)&&(raiz->idade<=18)){ system("cls"); printf("Escalao: Junior\n"); printf("Percurso: C\n"); printf("Nome: %s\n", raiz->nome); printf("Numero: %d\n", raiz->numero); printf("Idade: %d\n", raiz->idade); printf("Clube: %s\n", raiz->clube); printf("Hora de partida: %d-%d-%d\n", raiz->hp, raiz->mp, raiz->sp); printf("Hora de cheagada: %d-%d-%d\n\n", raiz->hc, raiz->mc, raiz->sc); system("pause");} } if(p==4){ if((raiz->idade>=18)){ system("cls"); printf("Escalao: Senior\n"); printf("Percurso: D\n"); printf("Nome: %s\n", raiz->nome); printf("Numero: %d\n", raiz->numero); printf("Idade: %d\n", raiz->idade); printf("Clube: %s\n", raiz->clube);
Rogrio Lopes & Joo Figueiredo 35

Relatrio do trabalho prtico

printf("Hora de partida: %d-%d-%d\n", raiz->hp, raiz->mp, raiz->sp); printf("Hora de cheagada: %d-%d-%d\n\n", raiz->hc, raiz->mc, raiz->sc); system("pause");}

ListarporP(raiz->esq,p); ListarporP(raiz->dir,p); } }

} void ListarporE(ATLETA *raiz,int p) { if(raiz!=NULL) {

if(p==1){ if((raiz->idade>=1)&&(raiz->idade<=14)){ system("cls"); printf("Escalao: Iniciado\n"); printf("Percurso: A\n"); printf("Nome: %s\n", raiz->nome); printf("Numero: %d\n", raiz->numero); printf("Idade: %d\n", raiz->idade); printf("Clube: %s\n", raiz->clube); printf("Hora de partida: %d-%d-%d\n", raiz->hp, raiz->mp, raiz->sp); printf("Hora de cheagada: %d-%d-%d\n\n", raiz->hc, raiz->mc, raiz->sc); system("pause");}} if(p==2){ if((raiz->idade>=15)&&(raiz->idade<=16)){
Rogrio Lopes & Joo Figueiredo 36

Relatrio do trabalho prtico

system("cls"); printf("Escalao: Juvenil\n"); printf("Percurso: B\n"); printf("Nome: %s\n", raiz->nome); printf("Numero: %d\n", raiz->numero); printf("Idade: %d\n", raiz->idade); printf("Clube: %s\n", raiz->clube); printf("Hora de partida: %d-%d-%d\n", raiz->hp, raiz->mp, raiz->sp); printf("Hora de cheagada: %d-%d-%d\n\n", raiz->hc, raiz->mc, raiz->sc); system("pause");}} if(p==3){ if((raiz->idade>=17)&&(raiz->idade<=18)){ system("cls"); printf("Escalao: Junior\n"); printf("Percurso: C\n"); printf("Nome: %s\n", raiz->nome); printf("Numero: %d\n", raiz->numero); printf("Idade: %d\n", raiz->idade); printf("Clube: %s\n", raiz->clube); printf("Hora de partida: %d-%d-%d\n", raiz->hp, raiz->mp, raiz->sp); printf("Hora de cheagada: %d-%d-%d\n\n", raiz->hc, raiz->mc, raiz->sc); system("pause");} } if(p==4){ if((raiz->idade>=18)){ system("cls"); printf("Escalao: Senior\n"); printf("Percurso: D\n"); printf("Nome: %s\n", raiz->nome); printf("Numero: %d\n", raiz->numero); printf("Idade: %d\n", raiz->idade); printf("Clube: %s\n", raiz->clube);
Rogrio Lopes & Joo Figueiredo 37

Relatrio do trabalho prtico

printf("Hora de partida: %d-%d-%d\n", raiz->hp, raiz->mp, raiz->sp); printf("Hora de cheagada: %d-%d-%d\n\n", raiz->hc, raiz->mc, raiz->sc); system("pause");} ListarporP(raiz->esq,p); ListarporP(raiz->dir,p); } } }

Atravs da funo main est classificado o menu, onde so introduzidos os dados dos atletas na primeira opo, seguido de dados restritos para a obteno de algumas informaes sobre os atletas, assim como listagens por percurso, consultas por percurso ou outros dados especificados anteriormente. int main() { int op, op2, n, id, hc, mc, sc, hp, mp, sp; char no[50], c[30]; char ide[20],idp[20]; char escolha; int per,esc; lista= carregar(lista); ATLETA *lista = NULL; menu(); scanf("%d", &op); fflush(stdin); while(op!=0) { switch(op) { case 1://inserir atleta system("cls"); printf("Insira o numero\n"); scanf("%d", &n); fflush(stdin); printf("Insira o nome\n"); scanf("%s", no); fflush(stdin); printf("Insira a idade\n"); scanf("%d", &id);

Rogrio Lopes & Joo Figueiredo

38

Relatrio do trabalho prtico

if((id>=1)&&(id<=14)){ printf("Escalao: Iniciado\n"); printf("Percurso: A\n");} else if((id>=15)&&(id<=16)){ printf("Escalao: Juvenil\n"); printf("Percurso: B\n");} else if((id>=17)&&(id<=18)){ printf("Escalao: Junior\n"); printf("Percurso: C\n");} else{ printf("Escalao: Senior\n"); printf("Percurso: D\n");} fflush(stdin); printf("Insira as horas de partida\n"); scanf("%d", &hp); fflush(stdin); printf("Insira os minutos de partida\n"); scanf("%d", &mp); fflush(stdin); printf("Insira os segundos de partida\n"); scanf("%d", &sp); fflush(stdin); printf("Insira o clube\n"); scanf("%s", c); fflush(stdin); printf("O atleta completou a prova [S/N] ?\n\n"); scanf("%c",&escolha); if ((escolha == 'S') || (escolha == 's')) { system ("cls"); printf("Insira as horas de chegada\n"); scanf("%d", &hc); fflush(stdin); printf("Insira os minutos de chegada\n"); scanf("%d", &mc); fflush(stdin); printf("Insira os segundos de chegada\n"); scanf("%d", &sc); fflush(stdin); }else if((escolha == 'N') || (escolha == 'n')){ hc=0; mc=0; sc=0; } lista = Inserir(lista, n, id, no, c, hp, mp, sp, hc, mc,sc); break; case 2:

Rogrio Lopes & Joo Figueiredo

39

Relatrio do trabalho prtico

system("cls"); printf("Insira o nome do atleta:\n"); scanf("%s", no); fflush(stdin); CNome(lista, no); system("pause"); break; case 3: system("cls"); terminaramprova(lista); system("pause"); break; case 4: gravar( n,id, hc, mc, sc, hp, mp, sp, no,c); break; case 5: system("cls"); printf("Qual o Percurso que deseja listar?\n"); printf("1->A\n"); printf("2->B\n"); printf("3->C\n"); printf("4->D\n"); scanf("%d",&per); fflush(stdin); ListarporP(lista,per); break; case 6: system("cls"); printf("Qual o Percurso que deseja listar?\n"); printf("1->Iniciado\n"); printf("2->Juvenil\n"); printf("3->Junior\n"); printf("4->Senior\n"); scanf("%d",&esc); fflush(stdin); ListarporE(lista,esc); break; } menu(); scanf("%d", &op); fflush(stdin); } return (0); }

Rogrio Lopes & Joo Figueiredo

40

Relatrio do trabalho prtico

3- Concluses
A realizao deste trabalho prtico permitiu aprofundar bastante o conhecimento prtico nas temticas de listas ligadas simples, listas duplamente ligadas e, por fim, rvores binrias de procura. Ser tambm de extrema importncia frisar a percepo prtica da utilidade e importncia das listas ligadas simples assim como das listas duplamente ligadas e, por fim, das rvores binrias de procura. As listas ligadas tm diversas vantagens, como por exemplo a adio ou remoo de um elemento numa determinada lista no obriga a mudanas em outros elementos, no obrigando tambm definio de um nmero mximo de elementos que uma lista possa ter. Uma lista ligada uma estrutura consideravelmente linear, constituda por clulas que apontam aos elementos seguintes da lista. Por outro lado, uma lista duplamente ligada trata-se da extenso de uma lista ligada simples, contendo dois apontadores contrariamente lista ligada simples que possui apenas um. Atravs de listas duplamente ligadas obtm-se um maior controlo de uma lista, o que se torna mais fivel, apesar da maior ocupao em termos de espao no disco. Por fim, uma rvore binria de procura, uma das mais importantes componentes da programao em C, trata-se de uma estrutura que poder no possuir qualquer elemento, ou poder tambm ter um s elemento com dois apontadores para duas estruturas distintas.

4- Objectivos realizados
No que diz respeito s duas primeiras aplicaes do enunciado, as mesmas so totalmente funcionais, funcionando exactamente de acordo com o proposto no enunciado do trabalho prtico

Rogrio Lopes & Joo Figueiredo

41

Relatrio do trabalho prtico

A terceira aplicao est quase completa, faltando apenas a gesto de uma lista ordenada por tempo de prova, assim como a funo que permite a leitura. Sendo assim, na nossa opinio foi conseguido um bom trabalho no geral, uma vez que o tempo para o realizar no foi muito devido a diversos encargos, mas no fim obteve-se sucesso atravs de bastante esforo dedicado sua realizao e melhoria.

5- Bibliografia
Linguagem C - Lus Damas 10 Edio Prof. Joo Carlos Silva, slides disponibilizados nas aulas da UC

Rogrio Lopes & Joo Figueiredo

42

Relatrio do trabalho prtico

autor

43

Você também pode gostar