Skip to content

Instantly share code, notes, and snippets.

@cpereira7
Created May 13, 2018 23:02
Show Gist options
  • Select an option

  • Save cpereira7/45b58c224d56a54966ce6fa78a4a20ea to your computer and use it in GitHub Desktop.

Select an option

Save cpereira7/45b58c224d56a54966ce6fa78a4a20ea to your computer and use it in GitHub Desktop.
Antigo exercício de listas ligadas em C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _CRT_SECURE_NO_WARNINGS
struct cliente
{
int nif;
char nome[100];
char morada[100];
char email[100];
int telefone;
float precoMaximo;
int anoMinimo;
int numQuartosMinimo;
float areaMinima;
};
struct noCliente
{
struct cliente elemento;
struct noCliente *seguinte;//Para o nó seguinte
};
void ler_ficheiro(struct noLivro *ListadeLivros)
{
int i = 0;
struct cliente CL;
FILE *ficheiro;
ficheiro = fopen("Clientes.txt", "r");
if (ficheiro == NULL)
{
perror("Erro ao abrir o ficheiro de dados\n");
}
else
{
printf("Inciada a leitura do ficheiro\n");
while (!feof(ficheiro))
{
fscanf(ficheiro, "%d\n", &(CL.nif));
fgets(&CL.nome, sizeof(CL.nome), ficheiro);
fgets(&CL.morada, sizeof(CL.morada), ficheiro);
fgets(&CL.email, sizeof(CL.email), ficheiro);
fscanf(ficheiro, "%d\n", &(CL.telefone));
fscanf(ficheiro, "%f\n", &(CL.precoMaximo));
fscanf(ficheiro, "%d\n", &(CL.anoMinimo));
fscanf(ficheiro, "%d\n", &(CL.numQuartosMinimo));
fscanf(ficheiro, "%f\n", &(CL.areaMinima));
//Adiciona livro à lista
AdicionarCliente_2(ListadeLivros, &CL);
i++;
}
fclose(ficheiro);
printf("Concluida a leitura do ficheiro");
}
}
struct noCliente *CriarCliente()
{
struct noCliente *noNovo;
noNovo = (struct noCliente*)malloc(sizeof(struct noCliente));
noNovo->seguinte = NULL;
strcpy(noNovo->elemento.email, "");
strcpy(noNovo->elemento.morada, "");
strcpy(noNovo->elemento.nome, "");
noNovo->elemento.anoMinimo = 0;
noNovo->elemento.areaMinima = 0;
noNovo->elemento.nif = 0;
noNovo->elemento.numQuartosMinimo = 0;
noNovo->elemento.precoMaximo = 0;
noNovo->elemento.telefone = 0;
return noNovo;
}
struct noCliente *PesquisarClienteNIF(struct noCliente *ListadeClientes, int nif)
{
struct noCliente *noActual = ListadeClientes;
//Percorre os nos da lista
while (noActual != NULL)
{
if (noActual->elemento.nif == nif)
{
break;
}
else
{
noActual = noActual->seguinte;
}
}
return noActual;
}
struct noCliente *PesquisarClienteNome(struct noCliente *ListadeClientes, char *nome)
{
struct noCliente *noActual = ListadeClientes;
//Percorre os nos da lista
while (noActual != NULL)
{
if (strcmp (noActual->elemento.nome, nome) == 0)
{
break;
}
else
{
noActual = noActual->seguinte;
}
}
return noActual;
}
int AdicionarCliente(struct noCliente *ListadeLivros, int nif, char *nome, char *morada, char *email,
int telefone, int precoMax, int anoMin, int nquartos, int area )
{
struct noCliente *noActual = ListadeLivros;
struct noCliente *noNovo;
//Verifica se o livro ja existe na lista ligada
if (PesquisarClienteNIF(ListadeLivros, nif) != NULL)
{
return -1;
}
//Verifica se a lista está vazia (possui apenas um no com dados vazios)
if (noActual->elemento.nif == 0)
{
//Localiza o ultimo nó da lista
while (noActual->seguinte != NULL)
{
noActual = noActual->seguinte;
}
//Aloca novo nó livro e liga-o à lista
noNovo = CriarCliente();
noActual->seguinte = noNovo;
noActual = noActual->seguinte;
}
strcpy(noActual->elemento.email, email);
strcpy(noActual->elemento.morada, morada);
strcpy(noActual->elemento.nome, nome);
noActual->elemento.anoMinimo = anoMin;
noActual->elemento.areaMinima = area;
noActual->elemento.nif = nif;
noActual->elemento.numQuartosMinimo = nquartos;
noActual->elemento.precoMaximo = precoMax;
noActual->elemento.telefone = telefone;
return 0;
}
int AdicionarCliente_2(struct noCliente *ListadeLivros, struct cliente *cl)
{
struct noCliente *noActual = ListadeLivros;
struct noCliente *noNovo;
//Verifica se o livro ja existe na lista ligada
if (PesquisarClienteNIF(ListadeLivros, cl->nif) != NULL)
{
return -1;
}
//Verifica se a lista está vazia (possui apenas um no com dados vazios)
if (noActual->elemento.nif == 0)
{
//Localiza o ultimo nó da lista
while (noActual->seguinte != NULL)
{
noActual = noActual->seguinte;
}
//Aloca novo nó livro e liga-o à lista
noNovo = CriarCliente();
noActual->seguinte = noNovo;
noActual = noActual->seguinte;
}
strcpy(noActual->elemento.email, cl->email);
strcpy(noActual->elemento.morada, cl->morada);
strcpy(noActual->elemento.nome, cl->nome);
noActual->elemento.anoMinimo = cl->anoMinimo;
noActual->elemento.areaMinima = cl->areaMinima;
noActual->elemento.nif = cl->nif;
noActual->elemento.numQuartosMinimo = cl->numQuartosMinimo;
noActual->elemento.precoMaximo = cl->precoMaximo;
noActual->elemento.telefone = cl->telefone;
return 0;
}
int remover_cliente(struct noCliente *ListadeClientes, int nif)
{
struct noCliente *noActual = ListadeClientes;
struct noCliente *noAnterior = NULL;
// percorre os nos da lista
while (noActual != NULL)
{
//Verifica se o Livro indicado existe na lista ligada
if (noActual->elemento.nif == nif)
{
break;
}
else
{
noAnterior = noActual;
noActual = noActual->seguinte;
}
}
if (noActual != NULL)
{
//Remove o nó livro indicado
if (noAnterior == NULL)
noAnterior = CriarCliente();
noAnterior->seguinte = noActual->seguinte;
free(noActual);
return 0;
}
return -1;
}
void MostrarLista(struct noCliente *ListadeLivros)
{
struct noCliente *noActual = ListadeLivros;
while (noActual != NULL)
{
if (noActual->elemento.nif != 0)
{
printf("NIF do cliente: %d\n", noActual->elemento.nif);
printf("Nome do cliente: ");
fputs(noActual->elemento.nome, stdout);
printf("Morada do cliente: ");
fputs(noActual->elemento.morada, stdout);
printf("Endereco eletronico do cliente: ");
fputs(noActual->elemento.email, stdout);
printf("Contacto telefonico do cliente: %d\n", noActual->elemento.telefone);
printf("Preco maximo desejado pelo cliente: %f\n", noActual->elemento.precoMaximo);
printf("Ano de construcao mais baixo desejado pelo cliente: %d\n", noActual->elemento.anoMinimo);
printf("Numero de quartos minimo desejado pelo cliente: %d\n", noActual->elemento.numQuartosMinimo);
printf("Area de ocupacao minima desejado pelo cliente: %6.2f\n", noActual->elemento.areaMinima);
}
noActual = noActual->seguinte;
}
}
void InserirNovoCliente(struct noCliente *ListadeLivros)
{
struct cliente CL;
printf("Insira o NIF do cliente:\n");
scanf("%d", &(CL.nif));
printf("Insira o Nome completo do cliente:\n");
fflush(stdin); // limpar o buffer, usando Windows
//__fpurge(stdin); // limpar o buffer, usandoUnix/Linux
fgets(&CL.nome , 80, stdin);
printf("Insira a Morada do cliente:\n");
fflush(stdin);
//__fpurge(stdin);
fgets(&CL.morada, 100, stdin);
printf("Insira o enderecoço eletronico (e-mail) do cliente:\n");
fflush(stdin);
//__fpurge(stdin);
fgets(&CL.email, 30, stdin);
printf("Insira o numero de Telefone do cliente:\n");
scanf("%d", &(CL.telefone));
printf("Insira o Preco maximo desejado:\n");
scanf("%f", &(CL.precoMaximo));
printf("Insira o Ano de construcao mais baixo desejado:\n");
scanf("%d", &(CL.anoMinimo));
printf("Insira o Numero de quartos minimo desejado:\n");
scanf("%d", &(CL.numQuartosMinimo));
printf("Insira a Area de ocupacao minima desejada:\n");
scanf("%f", &(CL.areaMinima));
AdicionarCliente_2(ListadeLivros, &CL);
}
void editarCliente(struct noCliente *ListadeClientes, int nif)
{
struct noCliente *CL = PesquisarClienteNIF(ListadeClientes, nif);
char op;
if (CL != NULL)
{
//printf("NIF actual: %d\n", &CL->elemento.nif);
printf("Alterar o NIF? (s/n): ");
fflush(stdin);
scanf("%c", &op);
switch (op)
{
default:
case 's':
printf("Insira o NIF do cliente:\n");
scanf("%d", &(CL->elemento.nif));
case 'n':
break;
}
//--------------------
printf("Nome actual: %s\n", &CL->elemento.nome);
printf("Alterar? (s/n): ");
fflush(stdin);
scanf("%c", &op);
switch (op)
{
default:
case 's':
printf("Insira o Nome completo do cliente:\n");
fflush(stdin); // limpar o buffer, usando Windows
//__fpurge(stdin); // limpar o buffer, usandoUnix/Linux
fgets(&CL->elemento.nome, 80, stdin);
case 'n':
break;
}
//--------------------
printf("Morada actual: %s\n", &CL->elemento.morada);
printf("Alterar? (s/n): ");
fflush(stdin);
scanf("%c", &op);
switch (op)
{
default:
case 's':
printf("Insira a Morada do cliente:\n");
fflush(stdin);
//__fpurge(stdin);
fgets(&CL->elemento.morada, 100, stdin);
case 'n':
break;
}
//--------------------
printf("Email actual: %s\n", &CL->elemento.email);
printf("Alterar? (s/n): ");
fflush(stdin);
scanf("%c", &op);
switch (op)
{
default:
case 's':
printf("Insira o enderecoço eletronico (e-mail) do cliente:\n");
fflush(stdin);
//__fpurge(stdin);
fgets(&CL->elemento.email, 30, stdin);
case 'n':
break;
}
//--------------------
printf("Telefone actual: %d\n", &CL->elemento.telefone);
printf("Alterar? (s/n): ");
fflush(stdin);
scanf("%c", &op);
switch (op)
{
default:
case 's':
printf("Insira o numero de Telefone do cliente:\n");
scanf("%d", &(CL->elemento.telefone));
case 'n':
break;
}
//--------------------
printf("Preco Maximo actual: %f\n", &CL->elemento.precoMaximo);
printf("Alterar? (s/n): ");
fflush(stdin);
scanf("%c", &op);
switch (op)
{
default:
case 's':
printf("Insira o Preco maximo desejado:\n");
scanf("%f", &(CL->elemento.precoMaximo));
case 'n':
break;
}
//--------------------
printf("Ano actual: %d\n", &CL->elemento.anoMinimo);
printf("Alterar? (s/n): ");
fflush(stdin);
scanf("%c", &op);
switch (op)
{
default:
case 's':
printf("Insira o Ano de construcao mais baixo desejado:\n");
scanf("%d", &(CL->elemento.anoMinimo));
case 'n':
break;
}
//--------------------
printf("Numero de Quartos actual: %d\n", &CL->elemento.numQuartosMinimo);
printf("Alterar? (s/n): ");
fflush(stdin);
scanf("%c", &op);
switch (op)
{
default:
case 's':
printf("Insira o Numero de quartos minimo desejado:\n");
scanf("%d", &(CL->elemento.numQuartosMinimo));
case 'n':
break;
}
//--------------------
printf("Area actual: %f\n", &CL->elemento.areaMinima);
printf("Alterar? (s/n): ");
fflush(stdin);
scanf("%c", &op);
switch (op)
{
default:
case 's':
printf("Insira a Area de ocupacao minima desejada:\n");
scanf("%f", &(CL->elemento.areaMinima));
case 'n':
break;
}
//--------------------
}
}
void guardar_clientes(struct noCliente *ListadeClientes)
{
struct noCliente *noActual = ListadeClientes;
FILE *fp;
//Actualiza a info
fp = fopen("Clientes.txt", "w");
if (fp == NULL)
{
perror("Erro ao abrir o ficheiro Clientes.txt\n");
}
else
{
printf("Iniciada a actualização do ficheiro Clientes.txt");
//percores os nos da lista
while (noActual != NULL)
{
if (noActual->elemento.nif != 0)
{
fprintf(fp, "%d\n", (&noActual->elemento)->nif);
fputs((&noActual->elemento)->nome, fp);
fputs((&noActual->elemento)->morada, fp);
fputs((&noActual->elemento)->email, fp);
fprintf(fp, "%d\n", (&noActual->elemento)->telefone);
fprintf(fp, "%d\n", (&noActual->elemento)->precoMaximo);
fprintf(fp, "%d\n", (&noActual->elemento)->anoMinimo);
fprintf(fp, "%d\n", (&noActual->elemento)->numQuartosMinimo);
fprintf(fp, "%f\n", (&noActual->elemento)->areaMinima);
}
noActual = noActual->seguinte; //Actualiza o nó
}
fclose(fp);
printf("Conluida a actualização do ficheiro livros.txt\n");
}
}
int TamanhodaLista(struct noCliente *ListadeClientes)
{
struct noCliente *noActual = ListadeClientes;
int n = 0;
// Percorre os nós da lista
while (noActual != NULL)
{
n = n + 1;
noActual = noActual->seguinte;
}
return n;
}
int compare(const void * a, const void * b)
{
return (*(float*)a - *(float*)b);
}
float* ordernarPrecos(struct noCliente *ListaClientes)
{
int n = TamanhodaLista(ListaClientes);
struct noCliente *noActual = ListaClientes;
float *a;
a = malloc(n * sizeof(float)); //alocação dinamica de um array, com tamanho variavel correspondente ao tamanho da lista
for (int i = 0; i < n; ++i)
{
a[i] = noActual->elemento.precoMaximo;
noActual = noActual->seguinte;
}
qsort(a, n, sizeof(float), compare);
return a;
}
void determinarMaiorPreco(struct noCliente *ListadeClientes)
{
int n = TamanhodaLista(ListadeClientes);
struct noCliente *noInicial = ListadeClientes;
float *a = ordernarPrecos(ListadeClientes);
int i = 0;
//Calculo do 3º Quartil
int Q_34 = (0.75)*(n + 1);
float preco34 = a[Q_34-1];
printf("Melhores Clientes:\n\n");
while (noInicial != NULL)
{
if (noInicial->elemento.precoMaximo >= preco34)
{
printf("NIF do cliente: %d\n", noInicial->elemento.nif);
printf("Nome do cliente: ");
fputs(noInicial->elemento.nome, stdout);
printf("Preco maximo desejado pelo cliente: %f\n", noInicial->elemento.precoMaximo);
}
noInicial = noInicial->seguinte;
}
}
void determinarVariaçãoPreço(struct noCliente *ListadeClientes)
{
int n = TamanhodaLista(ListadeClientes);
struct noCliente *noActual = ListadeClientes;
float *a = ordernarPrecos(ListadeClientes);
//Calculo da variação
float a1 = a[1];
float a2 = a[n-1];
float aVariacao = ((a2 - a1) / a1) * 100;
float bVariacao = (a2 - a1);
printf("Variacao de precos entre mais baixo e mais elevado: %3.2f por cento\n", aVariacao);
printf("O que corresponde a: %3.2f euros\n\n", bVariacao);
}
void determinarVariaçãoQuartos(struct noCliente *ListadeClientes)
{
int n = TamanhodaLista(ListadeClientes);
struct noCliente *noActual = ListadeClientes;
float *a;
a = malloc(n * sizeof(float)); //alocação dinamica de um array, com tamanho variavel correspondente ao tamanho da lista
for (int i = 0; i < n; ++i)
{
a[i] = noActual->elemento.numQuartosMinimo;
noActual = noActual->seguinte;
}
qsort(a, n, sizeof(float), compare);
//Calculo da variação
int a1 = a[1];
int a2 = a[n - 1];
int bVariacao = (a2 - a1);
printf("Variacao no numero de quartos minimos - diferenca de: %d quartos\n\n", bVariacao);
}
int main(){
struct noCliente *ListadeClientes = CriarCliente();
system("color a");
int MenuPrincipal, MenuSecundario;
int numero = 0;
char nome[100];
struct noCliente *cliente;
do {
printf("MENU PRINCIPAL\n");
printf(" 0 - SAIR\n");
printf(" 1 - FICHEIRO\n");
printf(" 2 - CLIENTES\n");
printf(" 3 - OPERACOES\n");
printf("Insira a opcao desejada: ");
scanf("%d", &MenuPrincipal);
switch (MenuPrincipal) {
case 0: break;
case 1: do{
printf("SUBMENU FICHEIRO\n");
printf(" 0 - SAIR\n");
printf(" 1 - Abrir\n");
printf(" 2 - Guardar\n");
printf(" 3 - Listar todos os clientes da lista\n");
printf(" 4 - Nova lista\n");
printf("Insira a opcao desejada: ");
scanf("%d", &MenuSecundario);
switch (MenuSecundario) {
case 0: break;
case 1: ler_ficheiro(ListadeClientes); break;
case 2: guardar_clientes(ListadeClientes); break;
case 3: MostrarLista(ListadeClientes); break;
case 4: ListadeClientes = CriarCliente(); break;
}
} while (MenuSecundario >= 1 && MenuSecundario <= 4);
break;
case 2: do{
printf("SUBMENU CLIENTES\n");
printf(" 0 - SAIR\n");
printf(" 1 - Inserir cliente\n");
printf(" 2 - Remover cliente\n");
printf(" 3 - Consultar cliente por NIF\n");
printf(" 4 - Consultar cliente por nome\n");
printf(" 5 - Alterar dados de cliente\n");
printf("Insira a opcao desejada: ");
scanf("%d", &MenuSecundario);
switch (MenuSecundario) {
case 0: break;
case 1: InserirNovoCliente(ListadeClientes); break;
case 2:
fflush(stdin);
printf("NIF:");
scanf("%d", &numero);
remover_cliente(ListadeClientes, numero);
break;
case 3:
fflush(stdin);
printf("NIF:");
scanf("%d", &numero);
cliente = PesquisarClienteNIF(ListadeClientes, numero);
if (cliente == NULL)
{
printf("Cliente nao existe...\n");
}
else
{
printf("NIF do cliente: %d\n", cliente->elemento.nif);
printf("Nome do cliente: ");
fputs(cliente->elemento.nome, stdout);
printf("Morada do cliente: ");
fputs(cliente->elemento.morada, stdout);
printf("Endereco eletronico do cliente: ");
fputs(cliente->elemento.email, stdout);
printf("Contacto telefonico do cliente: %d\n", cliente->elemento.telefone);
printf("Preco maximo desejado pelo cliente: %f\n", cliente->elemento.precoMaximo);
printf("Ano de construcao mais baixo desejado pelo cliente: %d\n", cliente->elemento.anoMinimo);
printf("Numero de quartos minimo desejado pelo cliente: %d\n", cliente->elemento.numQuartosMinimo);
printf("Area de ocupacao minima desejado pelo cliente: %6.2f\n", cliente->elemento.areaMinima);
}
fflush(stdin);
break;
case 4:
fflush(stdin);
printf("Nome:");
fgets(nome, sizeof nome, stdin); /* inclui o caracter /n*/
if (strchr(nome, '\n') != NULL) //se string contem \n
{
*(strchr(nome, '\n')) = '\0'; //substituir por fim de string
}
cliente = PesquisarClienteNome(ListadeClientes, nome);
if (cliente == NULL)
{
printf("Cliente nao existe...\n");
}
else
{
printf("NIF do cliente: %d\n", cliente->elemento.nif);
printf("Nome do cliente: ");
fputs(cliente->elemento.nome, stdout);
printf("Morada do cliente: ");
fputs(cliente->elemento.morada, stdout);
printf("Endereco eletronico do cliente: ");
fputs(cliente->elemento.email, stdout);
printf("Contacto telefonico do cliente: %d\n", cliente->elemento.telefone);
printf("Preco maximo desejado pelo cliente: %f\n", cliente->elemento.precoMaximo);
printf("Ano de construcao mais baixo desejado pelo cliente: %d\n", cliente->elemento.anoMinimo);
printf("Numero de quartos minimo desejado pelo cliente: %d\n", cliente->elemento.numQuartosMinimo);
printf("Area de ocupacao minima desejado pelo cliente: %6.2f\n", cliente->elemento.areaMinima);
}
fflush(stdin);
break;
case 5:
fflush(stdin);
int nif = 1;
printf("NIf do cliente a alterar: ");
scanf("%d", &nif);
fflush(stdin);
editarCliente(ListadeClientes, nif); break;
}
} while (MenuSecundario >= 1 && MenuSecundario <= 5);
break;
case 3: do{
printf("SUBMENU OPERACOES\n");
printf(" 0 - SAIR\n");
printf(" 1 - Quantos clientes estao na lista\n");
printf(" 2 - Quais os clientes com o maior preco maximo desejado\n");
printf(" 3 - Qual a variacao de precos maximos dos clientes da lista\n");
printf(" 4 - Qual a variacao de numero de quartos dos clientes da lista\n");
printf("Insira a opcao desejada: ");
scanf("%d", &MenuSecundario);
switch (MenuSecundario) {
case 0: break;
case 1:
printf("%d \n\n", TamanhodaLista(ListadeClientes));
break;
case 2:
determinarMaiorPreco(ListadeClientes);
break;
case 3:
determinarVariaçãoPreço(ListadeClientes);
; break;
case 4:
determinarVariaçãoQuartos(ListadeClientes);
break;
}
} while (MenuSecundario >= 1 && MenuSecundario <= 4);
break;
}
} while (MenuPrincipal >= 1 && MenuPrincipal <= 3);
printf("Carregar em ENTER para terminar ...");
fflush(stdin); // Windows
//__fpurge(stdin); // Unix/Linux
getchar();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment