Gabarito da Lista 8 M�dulo 8: Aula 10: Tipos de dados avan�ados Aula 11: Tipos de dados definidos pelo usu�rio Exerc�cio 1: P�gina ca20.html Considerando o conceito e finalidade dos modificadores de tipo, relacione as afirmativas com as palavras reservadas correspondentes (todas as afirmativas devem ser preenchidas com o
n�mero relacionado ao modificador correspondente, e existe pelo menos uma afirmativa para cada modificador): ( 1 ) informa ao
compilador que o valor da vari�vel n�o pode ser alterado por nenhum comando do programa, mas que pode ser inicializado Exerc�cio 2: P�gina ca60.html
Note que neste programa estamos usando uma string (buffer) apenas para efetuar a leitura de cada string. Ap�s efetuada a leitura, alocamos no vetor de ponteiros para char a quantidade exata de caracteres necess�rios para o armazenamento da string lida e efetuamos a sua c�pia para esta regi�o de mem�ria usando strcpy. Exerc�cio 3: P�gina ca70.html
Exerc�cio 4: P�gina cb10.html
Exerc�cio 5: P�gina cb20.html
Exerc�cio 6: P�gina cb70.html:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 100 typedef struct tag_restaurante { char *nome; char *endereco; char tipo_comida; int nota; struct tag_restaurante *proximo; } Restaurante; /* Prototipos das funcoes */ void inserir(Restaurante **cabeca); /* Insere um restaurante na lista */ void listar (Restaurante *cabeca, FILE *arquivo); /* Apresenta todos os restaurantes na tela ou em um arquivo*/ Restaurante* le_arquivo(FILE *arquivo); /* Le a lista de restaurantes a partir de um arquivo */ void listar_seletivamente(Restaurante *cabeca, char *criterio, char *valor); /* Apresenta somente os restaurantes que satisfa�am determinado crit�rio */ FILE * abre_arquivo(FILE *arquivo, const char * modo); void le_dados_no(Restaurante *novono); void imprime_no( FILE *arquivo, Restaurante * noatual); Restaurante* desaloca_lista(Restaurante* cabeca); void aloca_copia(char ** , char* ); int main() { Restaurante *cabeca = NULL; /* Ponteiro para a cabeca da lista */ char q; /* Caractere para receber a opcao do usuario */ FILE *arquivo = NULL; /* Ponteiro para FILE: arquivo que ser� lido ou escrito */ char nota[5]; /* nota para comparacao vai ser lida como char */ do { printf("\n\nOpcoes: \ \nI -> para inserir novo restaurante; \ \nL -> para listar todos Restaurantes; \ \nA -> para ler lista de restaurantes de um arquivo;\ \nG -> para gravar lista de Restaurantes para arquivo; \ \nN -> Para listar os restaurantes com nota superior a um valor; \ \nT -> Para listar os restaurantes de determinado tipo; \ \nS -> para sair \n:"); fflush(stdin); /* Limpa o buffer de entrada */ scanf("%c", &q); /* Le a opcao do usuario */ fflush(stdin); /* Limpa o buffer de entrada */ switch(q) { case 'i': case 'I': /* Inserir novo no na lista */ inserir(&cabeca); break; case 'l': case 'L': /* Listar no video a lista de restaurantes */ listar(cabeca, stdout); printf("\n Aperte <enter> para continuar"); fflush(stdin); scanf("%c",&q); fflush(stdin); break; case 'a': case 'A': /* Ler a lista a partir de arquivo */ arquivo = abre_arquivo(arquivo, "r"); if(arquivo) { cabeca = desaloca_lista(cabeca); /* Se havia lista anterior, ela e' desalocada */ cabeca = le_arquivo(arquivo); /* Le arquivo e retorna ponteiro para cabeca da lista */ fclose(arquivo); /* Fecha o arquivo, pois nao precisa mais dele */ } break; case 'g':case 'G': /* Grava a lista para um arquivo */ arquivo = abre_arquivo(arquivo,"w"); if(arquivo) { listar(cabeca, arquivo); /* Grava o arquivo */ fclose(arquivo); /* Fecha o arquivo */ } break; case 'n': case 'N': /* Lista restaurantes com nota superior a um valor */ printf("\n\nNota do restaurante deve ser superior a:"); gets(nota); listar_seletivamente(cabeca, "nota", nota); break; case 't': case 'T': /* Lista restaurantes por tipo de comida */ printf("\n\nQual tipo de comida?: \ \nB -> Brasileira; \ \nC -> Chinesa; \ \nF -> Francesa; \ \nI -> Italiana; \ \nJ -> Japonesa; \ \nO -> Outro tipo.\n:"); fflush(stdin); scanf("%c", &q); fflush(stdin); listar_seletivamente(cabeca, "tipo_comida", &q); break; case 's': case 'S': /* Sair do programa */ break; default: printf("\n\n Opcao nao valida"); } } while ((q != 's') && (q != 'S') ); cabeca = desaloca_lista(cabeca); /* Saindo do programa, desaloca a lista alocada */ } /* Desaloca a memoria alocada para os elementos da lista */ Restaurante* desaloca_lista(Restaurante* cabeca) { Restaurante* noatual; noatual = cabeca; while (noatual != NULL) { cabeca = noatual->proximo; /* Armazena em cabeca o proximo no */ free(noatual->nome); /* Nao esquecer de desalocar nome */ free(noatual->endereco); /* e endereco */ free(noatual); /* Desaloca o no atual */ noatual = cabeca; /* Faz no atual apontar para o proximo no */ } return cabeca; } /* Lista todos os elementos presentes na lista encadeada */ void listar (Restaurante *noatual, FILE *arquivo) { while( noatual != NULL) /* Enquanto nao chega no fim da lista */ { imprime_no(arquivo,noatual); /* Imprime o no atual */ noatual = noatual->proximo; /* Faz noatual apontar para o proximo no */ } } /* Lista os elementos de maneira seletiva, seguindo criterios especificados em criterio e dependentes do valor */ void listar_seletivamente(Restaurante *noatual, char *criterio, char *valor) { while( noatual != NULL) /* Enquanto nao chega no fim da lista */ { if(!strcmp(criterio,"tipo_comida")) /* Criterio de comparacao e' o tipo de comida */ { if(*valor == noatual->tipo_comida) imprime_no(stdout, noatual); } else { if(!strcmp(criterio,"nota")) /* Criterio de comparacao e' a nota */ if(atoi(valor) <= noatual->nota) imprime_no(stdout,noatual); } noatual = noatual->proximo; /* Faz noatual apontar para o proximo no */ } } /* Imprime um no da lista no arquivo especificado */ void imprime_no( FILE *arquivo, Restaurante * noatual) { fprintf(arquivo,"\nNome : %s", noatual->nome); fprintf(arquivo,"\nEndereco: %s", noatual->endereco); fprintf(arquivo,"\nCozinha : %c", noatual->tipo_comida); fprintf(arquivo,"\nNota : %d\n", noatual->nota); } /* Funcao para abrir arquivo */ FILE* abre_arquivo(FILE* arquivo, const char* modo) { static char nome[20]=""; char novonome[20]; if(strlen(nome))printf("Nome atual = %s , se quiser mante-lo responda com um enter", nome); printf("\nEntre com o nome do arquivo:"); gets(novonome); if(strlen(novonome)) strcpy(nome,novonome); arquivo = fopen (nome, modo); if(!arquivo) printf("Problema na abertura do arquivo %s", nome); return arquivo; } /* Funcao para inserir um novo no, ao final da lista */ void inserir (Restaurante **cabeca) /* Veja que o parametro e' um ponteiro duplo ... */ { Restaurante *noatual, *novono; if (*cabeca == NULL) /* Se ainda nao existe nenhum Restaurante na lista */ { /* cria o no cabeca */ *cabeca = (Restaurante *) malloc(sizeof(Restaurante)); novono = *cabeca; } else { /* Se ja existem elementos na lista, deve percorre-la ate' o seu final e inserir o novo elemento */ noatual = *cabeca; while(noatual->proximo != NULL) noatual = noatual->proximo; /* Ao final do while, noatual aponta para o ultimo no */ novono = (Restaurante *) malloc(sizeof(Restaurante));/* Aloca memoria para o novo no */ noatual->proximo = novono; /* Faz o ultimo no apontar para o novo no */ } le_dados_no(novono); } /* Entra com os dados via teclado e armazena no no da lista */ void le_dados_no(Restaurante *novono) { char buffer[MAX]; printf("\nNome do Restaurante:"); gets(buffer); novono->nome = (char *) malloc((strlen(buffer)+1)*sizeof(char)); strcpy(novono->nome,buffer); printf("\nEndereco do Restaurante:"); gets(buffer); novono->endereco = (char *) malloc((strlen(buffer)+1)*sizeof(char)); strcpy(novono->endereco,buffer); printf("\n\nQual tipo de comida?: \ \nB -> Brasileira; \ \nC -> Chinesa; \ \nF -> Francesa; \ \nI -> Italiana; \ \nJ -> Japonesa; \ \nO -> Outro tipo.\n:"); fflush(stdin); scanf("%c",&(novono->tipo_comida)); fflush(stdin); printf("\n\n Nota para o restaurante:"); scanf("%d",&(novono->nota)); novono->proximo = NULL; } /* Le a lista de restaurantes, armazenada em um arquivo Retorna o ponteiro para o no cabeca da lista */ Restaurante* le_arquivo(FILE *arquivo) { char buffer[MAX+10], nome[MAX],endereco[MAX]; char comida; Restaurante *cabeca = NULL; Restaurante *noatual = NULL; int nota; while(!feof(arquivo)) { fgets(buffer,MAX,arquivo); if(strstr(buffer,"Nome :"))strcpy(nome,buffer+10); /*strstr verifica se a string2 ocorre na string1: esta' em string.h */ else if(strstr(buffer,"Endereco:")) strcpy(endereco,buffer+10); else if(strstr(buffer,"Cozinha :")) comida = buffer[10]; else if(strstr(buffer, "Nota :")) { nota = atoi(buffer+9); if(cabeca == NULL) { /* cria o no cabeca */ cabeca = (Restaurante *) malloc(sizeof(Restaurante)); noatual = cabeca; } else { noatual->proximo = (Restaurante *) malloc(sizeof(Restaurante)); noatual = noatual->proximo; } aloca_copia(&(noatual->nome),nome); aloca_copia(&(noatual->endereco), endereco); noatual->tipo_comida = comida; noatual->nota = nota; noatual->proximo = NULL; } } return cabeca; } /* Esta funcao, ao mesmo tempo que aloca uma string com tamanho igual a da segunda string, faz a copia da segunda string para a primeira */ void aloca_copia(char ** str_alocada, char* str_copiada) { int i; *str_alocada = (char *) malloc((strlen(str_copiada)+1)*sizeof(char)); for(i=0; (str_copiada[i] && (str_copiada[i] != '\n')); i++) *((*str_alocada)+i) = str_copiada[i]; *((*str_alocada)+i) = 0; } Exerc�cios de Fixa��o:Exerc�cio 1: Prosseguindo o exerc�cio da pagina cb10.html, crie uma estrutura chamada ret�ngulo, que possua duas estruturas ponto (o ponto superior esquerdo e o ponto inferior direito). Fa�a um programa que receba (via teclado ou arquivo) as informa��es acerca de um ret�ngulo (as coordenadas dos dois pontos), e informe dados interessantes sobre o ret�ngulo, como a �rea, o comprimento da diagonal e o comprimento de cada aresta. Solu��o: typedef struct _ponto /* Aqui usa-se typedef para dar o nome */ typedef struct _retangulo /* Idem anterior */ void le_ponto(ponto *p, char *); void main(void) void le_ponto(ponto *p, char *s) float diagonal(retangulo r) int area(retangulo r) void arestas(retangulo r) Coment�rios:
Solu��o: void main() Exerc�cio 3: Solu��o: #include <stdio.h>#include <math.h> typedef struct _ponto { typedef struct _retangulo { ponto le_ponto(char *); void main(void) printf("\nPontos do retangulo:\n"); ponto le_ponto(char *s) float diagonal(retangulo *r) int area(retangulo *r) void arestas(retangulo *r) Coment�rios: DESAFIO:Exerc�cio 4: Solu��o: /* -------- Definicao dos tipos a serem usados */ typedef struct ficha_pessoal /* Tipo tPessoal: */ typedef struct _lista /* Tipo tLista: */ /* ----------- Prototipos das funcoes */ /* ---------------------------------------------------------- void main(void) printf("\n\n Gerenciador de dados: Versao 1.0"); /* --> Le o nome da lista com a qual vai trabalhar */ /* --> Le o arquivo e guarda na memoria */ if (lista.fichas == NULL) /* --> Comeca o loop principal */ /* --> Salva arquivo na saida */ /* --------------------------------------------------------- /* --------------------------------------------------------- tLista ad_reg(tLista lista) /* Le o novo registro */ /* Primeiro aloca a memoria necessaria para a nova lista... */ /* Copia o novo registro... */ /* Copia os registros antigos... */ /* Libera a
memoria da primeira lista.. */ /* retorna a nova lista */ /* ------------------------------------------------------- void find(tLista lista) /* Solicita a expressao de busca */ /* Varre a lista procurando a primeira ocorrencia da expressao */ /* -------------------------------------------------------- void altera(tLista lista) printf("\nDigite o numero do registro que deseja alterar: ");
/* Le o novo registro */ /* Atualiza na lista */ /* --------------------------------------------------------- tLista le_arquivo(FILE *arq) /* Le o tamanho do arquivo (qtos registros possui) */ /* Aloca a memoria necessaria para armazenar o arquivo /* retorna a lista criada */ /* ----------------------------------------------------------- void salva(FILE *arq, tLista l) /* ----------------------------------------------------------- void le_reg(tPessoal *reg) /* ---------------------------------------------------------- void le_str(char *s, int n, FILE *arq) /*
---------------------------------------------------------- void imprime(tPessoal f) Coment�rios: + strchr(char *s, char c): Esta fun��o retorna um apontador para a primeira ocorr�ncia
de c em s, ou NULL caso n�o encontre. Curso de C do CPDEE/UFMG - 1996-1999 |