Ir para conteúdo

Melhoria de Atividade da Faculdade


Tales Oliver

Posts Recomendados

Olá pessoal, sou novo aqui e iniciante no aprendizado.

Estou fazendo Faculdade de ADS; e como Portfólio do 1º Semestre tivemos que começar a desenvolver um programa.

Esse programa deveria ser em C.

E deveria conter algumas obrigações.

O usuário deverá cadastrar denúncias de focos de Dengue. Ele também pode visualizar as suas denúncias e excluí-las.

O máximo é de 20 denúncias.

Anexei o código como eu entreguei, porém, não está perfeito.

Tem alguns problemas e não sei como resolver.

Gostaria dou auxílio de você sobre o que eu devo fazer para que as funções sejam completas corretamente.

É a minha primeira publicação, então não conheço bem as regras.

CÓDIGO_ENTREGUE_ASSIM.c

Link para o comentário
Compartilhar em outros sites

Dei uma olhada no código e fiz algumas alterações, algumas simples, outras mais drásticas, mas mantendo o espírito do código original. Vou mostrando o código e explicando na sequência.

 

//BIBLIOTECAS
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>

//CONSTANTES
#define FILA_TAMANHO 20
#define ESTADO_TAMANHO 51+1
#define CIDADE_TAMANHO 51+1
#define BAIRRO_TAMANHO 51+1
#define RUA_TAMANHO 101+1

Mantive as mesmas bibliotecas. Adicionei mais constantes, baseadas nos tamanhos das strings da struct Denuncia. As definições das constantes estão em caixa alta por padrões adotados em outros códigos, porém isso é totalmente opcional. O +1 explicarei depois.

 

//DEFINIÇÃO DAS STRUCUTS
typedef struct Denuncia {
	char estado[ESTADO_TAMANHO];
	char cidade[CIDADE_TAMANHO];
	char bairro[BAIRRO_TAMANHO];
	char rua[RUA_TAMANHO];
	int numero;
} Denuncia;

typedef struct FilaDenuncias {
	Denuncia denuncias[FILA_TAMANHO];
	int tamanhoDaFila;
} FilaDenuncias;

A struct Denuncia teve alterações nos campos numero, ini e fim. O campo numero não é mais um array de ints, em vez disso, passa a ser um int comum. Os campos ini e fim foram removidos pois nada no código fazia referência a eles.

Além disso, criei um novo struct FilaDenuncias, que agrega tanto o array de denúncias quanto o total de denúncias inseridas. Note que não há mais declarações globais de variáveis.

 

//PROTOTIPAÇÃO
void Denuncia_Inserir(FilaDenuncias *fila);
void Denuncia_Excluir(FilaDenuncias *fila);
void Denuncia_Imprimir(FilaDenuncias *fila);
int Menu_Executar();
void Pausa();
void Remover_EOL(char* str);

Aqui começam as mudanças mais brabas. Como não há mais a fila global de denuncias, para cada operação que deve ser executada na fila, esta deve ser passada por referência, exceto na função Denuncia_Imprimir, onde é admissível passar a fila por valor.

A função de exibir o menu passa também a gerenciar a entrada do usuário, por isso a mudança do nome para Menu_Executar. O retorno agora é int, pois a função retornará a opção do usuário.

Outras duas funções foram adicionadas. Pausa foi criada para eliminar as chamadas do system("pause"), de modo a tornar o código mais portável. Remover_Char foi criada para eliminar caracteres específicos de uma string. Seu uso será justificado depois.

 

Agora, para a função main:

int main(){
	// DECLARAÇÕES
	int op = -1;
	FilaDenuncias filaDenuncias;
	filaDenuncias.tamanhoDaFila = 0;
	
	// INCLUINDO PT-BR
	setlocale(LC_ALL, "Portuguese");
	
	...

	return 0;
}

Note que as estruturas que antes eram de escopo global passam a ser localmente declaradas em main. Uma fila de denúncias é inicializada.

 

int main(){
	...

	while ((op = Menu_Executar()) != 0) {
		switch (op){
			case 1:		Denuncia_Inserir(&filaDenuncias);		break;
			case 2:		Denuncia_Imprimir(&filaDenuncias);	break;
			case 3:		Denuncia_Excluir(&filaDenuncias);		break;
			default:	printf("Opcao Inválida \n\n");			break;
		}
		Pausa();
	}
	return 0;
}

No loop principal da aplicação, a condicional chama a própria função Menu_Executar. As funções  agora necessitam da referência da fila de denúncias. Após cada ação, o programa pausa.

 

Agora, a implementação de cada função

//ADICIONAR ELEMENTO AO FIM DA FILA
void Denuncia_Inserir(FilaDenuncias *fila){
	int i = fila->tamanhoDaFila;
	if (fila->tamanhoDaFila == FILA_TAMANHO){
		...
	} else {
		...
	}
}

Essa foi a função que teve as mudanças mais radicais. Na primeira linha, criei uma variável temporária "i" para não ter que escrever fila->tamanhoDaFila o tempo todo e deixar o código mais limpo. A verificação feita para não exceder o tamanho máximo do array de denúncias agora é feito com a constante definida no início do código.

 

//ADICIONAR ELEMENTO AO FIM DA FILA
void Denuncia_Inserir(FilaDenuncias *fila){
	int i = fila->tamanhoDaFila;
	if (fila->tamanhoDaFila == FILA_TAMANHO){
		...
	} else {
		while(getchar() != '\n');
		
		printf("Digite o Estado: ");
		fgets(fila->denuncias[i].estado, ESTADO_TAMANHO, stdin);
		Remover_EOL(fila->denuncias[i].estado);
		...
		printf("Digite o Número do Imóvel: ");
		scanf("%d", &(fila->denuncias[i].numero));

		fila->tamanhoDaFila++;

		printf("Denúncia cadastrada!\n");
	}
}

A lógica principal da inserção de denúncias. A primeira linha (while(getchar() != '\n') limpa o buffer de teclas pressionadas (stdin) até encontrar um '\n'. Isso faz com que a primeira entrada da denúncia (estado) não seja ignorada com o '\n' gerado pelo pressionar do enter utilizado para entrar na opção.

Os campos que são strings (char*) são preenchidos com a função fgets, e não mais com a função scanf. A função fgets lê bytes de um arquivo até um número especificado de bytes ou encontrar uma quebra de linha ou fim do arquivo (EOF). O arquivo que será lido na verdade é o stdin, que é um arquivo "interno" da linguagem que armazena as teclas pressionadas. Ao fim, os caracteres são escritos na string designada. Depois disso, é removido o caractere '\n' gerado por causa da entrada no fgets através da função Remover_EOL. O número de caracteres máximo definido no início é +1 para que se possa comportar esse '\n' adicional. Para a cidade, bairro e rua, a lógica é a mesma.

O número é lido apenas uma vez.

No fim, o tamanho da fila é alterado.

 

//EXCLUIR O PRIMEIRO ELEMENTO DA FILA
void Denuncia_Excluir(FilaDenuncias *fila){
	if (fila->tamanhoDaFila == 0){
		printf("Não há Denúncias cadastradas...\n");
		printf("Cadastre as suas denúncias...\n\n");
	}else {
		int i;
		for (i = 0; i < fila->tamanhoDaFila; i++){
        		fila->denuncias[i] = fila->denuncias[i+1];
        	}
        	fila->tamanhoDaFila--;
        	printf("Denúncia excluída!\n");
        }      
}

Esta é a função que exclui a primeira denúncia da fila. Não foi muito alterada, exceto pela remoção de uma linha que, creio eu, sobrescrevia a denúncia na antiga posição da denúncia mais nova, que é desnecessária, em termos práticos.

 

//IMPRIMIR O CONTEÚDO DAS DENÚNCIAS
void Denuncia_Imprimir(FilaDenuncias *fila){
	int i;
	if (fila->tamanhoDaFila == 0){
		printf("Não há denúncias cadastradas.\n");
		printf("Cadastre alguma denúncia...\n\n");
	}else {
		printf("DENÚNCIAS CADASTRADAS\n");
		for (i = 0; i < fila->tamanhoDaFila; i++){
			printf("\n");
			printf("Estado: %s \n", fila->denuncias[i].estado);
			printf("Cidade: %s \n", fila->denuncias[i].cidade);
			printf("Bairro: %s \n", fila->denuncias[i].bairro);
			printf("Rua: %s \n", fila->denuncias[i].rua);
			printf("Número: %d \n\n", fila->denuncias[i].numero);
		}
	}
}

Função para imprimir na tela as denúncias. Pouca coisa mudou, também. No entanto, note o uso dos operadores . e ->. Deve-se tomar cuidado aqui e em outros pontos do código onde esses operadores são usados. A variável "fila" é um ponteiro para uma FilaDenuncias, e não uma FilaDenuncias em si! Para acessar os membros da estrutura FilaDenuncias a qual "fila" aponta, usa-se ->: fila->denuncias.

Note, agora, que denuncias não é um ponteiro, ele é um próprio exemplo direto da struct denuncia. Portanto, para acessar os membros de denuncias basta usar o .: denuncias.estado.

Juntando tudo, fila->denuncias.estado é o campo "estado" da estrutura "denuncias", que por sua vez é um campo de uma FilaDenuncias apontada por "fila".

 

int Menu_Executar(){
	int op;
	printf("Escolha uma opção:\n");
	printf("1- Cadastrar Denúncia\n");
	printf("2- Exibir Denúncia\n");
	printf("3- Excluir Denúncia\n");
	printf("0- Sair\n\n");
	printf("Digite aqui: ");
	scanf("%d", &op);
	return op;
}

A função que antes apenas exibia o menu agora também gerencia a entrada da opção.

 

void Pausa()
{
	printf("Pressione enter para continuar...\n");
	while(getchar() != '\n');
	getchar();
}

Essa função foi criada para lidar com a pausa e substituir as linhas system("pause"). A função system passa um comando para o sistema operacional executar, que nesse caso é "pause". Ocorre que a chamada "pause" funcionará apenas em Windows. De modo a tornar o programa agnóstico de SO, criei essa função. a linha while(getchar() != '\n') funciona como ele é usado na função de inserir denúncia, para que qualquer '\n' no fluxo de entrada não seja capturado pelo getchar() subsequente, fazendo que a pausa seja ignorada.

 

void Remover_EOL(char* str)
{
	char* posicao = strchr(str, '\n');
	if (posicao != NULL)
		*posicao = '\0';
}

Finalmente, a função que remove o '\n' no final da string. A função strchr retorna um ponteiro para a primeira ocorrência do char solicitado (que aqui é um '\n'.  Se for encontrado, a linha *posicao = '\0'" faz com que o local onde aponta "posição" seja alterado para '\0', que indica final de uma string.

 

O código completo tá em anexo. Boa sorte com os estudos e aproveite!

 

dengue.c

Link para o comentário
Compartilhar em outros sites

  • 3 semanas depois...

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...