Jump to content
Briooosa

Projecto em C: desafio

Recommended Posts

Briooosa

boas,este é o codigo de um projecto que fiz para a cadeira de programação de computadores,com listas,resolvi colocar porque á pouca informaçao sobre esta  materia.

-ele tem um bugzito,lol,mas passa despercebido,até me admirei pela prof ter reparado,lol,mas graças a isso só tive 3.7 em 4.descubram lá qual é?

#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

typedef struct nos_de_chamadas *list2;

typedef struct y						//estrutura para as chamadas
{
char orig[10];
char dest[10];
float duracao;
}chamada;

typedef struct nos_de_chamadas
{
chamada cont2;					// dado do elemento da lista
struct list2 *seguinte;// ponteiro para o elemento seguinte
}n;

typedef struct{			//estrutura para o novo contacto
char num_telefone[10];
char Nome[50];
int tipo_utilizador;
list2 n;
}contacto;

typedef struct nos_da_lista
{
contacto cont;						// dado do elemento da lista
struct list *seguinte;		// ponteiro para o elemento seguinte
}NO;

typedef struct nos_da_lista *list;

list cria_lista(void);
list2 cria_lista2(void);
void menu();
void insere_contacto(list lista, contacto c);
contacto novo_telefone(list lista);
void imprime_lista (list lista);
void imprime_contacto(contacto cont);
void imprimetudo(list lista);
int encontra_posicao(list lista, char num[10]);
void encontra_contacto(list lista, int n, list *ant, list *actual);
void elimina_contacto(list lista, char num[10]);
void insere_chamada(list lista, char num[10]);
void nova_chamada(list2 lista,chamada c);
void imprime_chamadas(list lista, int n);
void imprime_chamada(chamada cont2);
void gravar_dados(list lista);
void ler_dados(list lista);
void calcula_conta(list lista,int num);
float custo_chamada(list lista,chamada c);
chamada pede_chamada(char orig[10]);


//------------------------------------------------------------------
void main(){

list lista = cria_lista();//cria a lista para os contactos
int op,x;
char num[10];
int mudanca=0;
char resp;
do
{

	menu();

	printf("Opcao: ");
	scanf("%d", &op);

	switch(op)
	{
		case 1: printf("Inserir novo telefone\n");
				insere_contacto(lista,novo_telefone(lista));
				mudanca=1;
				break;

		case 2: printf("Listar telefones\n"); 
				imprimetudo(lista);
				break;

		case 3: printf("Remover telefone\n"); 
				printf("Numero de telefone a remover\n");
				scanf("%s", &num);

				x=encontra_posicao(lista,num);//verifica se o numero existe na lista
				if(x<0)
				{
					printf("numero nao existe\n");
				}
				else			//se existir apaga o nó que corresponde a esse numero
				{
					elimina_contacto(lista, num);
					printf("contacto removido\n");
				}
				mudanca=1;
				break;


		case 4: printf("Voce Seleccionou a opcao: Inserir nova chamada\n");
				printf("numero de telefone de origem\n");
				scanf("%s",&num);
				x=encontra_posicao(lista,num);

				if(x<0)				//verifica se o numero existe na lista
				{
					printf("numero nao pertence a empresa\n");
				}
				else
				{
					insere_chamada(lista, num);
				}
				mudanca=1;
				break;

		case 5: printf("Voce Seleccionou a opcao: Consultar chamadas de telefone\n"); 
				printf("numero de telefone da empresa\n");
				scanf("%s",&num);

				x=encontra_posicao(lista,num);//verifica se o numero existe na lista
				if(x<0)
				{
					printf("numero nao pertence a empresa\n");
				}
				else
				{
					imprime_chamadas(lista, x);	
				}
				break;

		case 6: printf("Voce Seleccionou a opcao: Calcular conta de telefone\n");
				printf("numero de telefone da empresa\n");
				scanf("%s",&num);

				x=encontra_posicao(lista,num);//verifica se o numero existe na lista
				if(x<0)
				{
					printf("numero nao pertence a empresa\n");
				}
				else
				{
					calcula_conta(lista,x);
				}
				break;

		case 7: printf("Voce Seleccionou a opcao: Guardar informacao\n"); 
				gravar_dados(lista);
				mudanca=0;
				break;

		case 8: printf("Voce Seleccionou a opcao: Ler informacao\n"); 
				ler_dados(lista);
				mudanca=1;
				break;

		case 9: printf("Voce Seleccionou a opcao: Sair\n"); 
				if(mudanca==1)	//salvaguar a hipotese de o utilizador
						        //fazer alteraçoes e sair sem guardar
				{
					printf("deseja guardar a informacao?sim(s) nao(n))\n");
					scanf("%s",&resp);
					if(stricmp(&resp, "s") == 0)
						gravar_dados(lista);
				}
				break;

		default : printf("opcao invalida\n");

	}




}while(op != 9);
}

//--------------------------------------------------
//calcular conta das chamadas efectuadas por um numero da empresa
void calcula_conta(list lista,int num)
{

list ant;
list actual;
contacto cont;
chamada cont2;
list2 li;
float preco=0;

if(num >= 0)
{
// encontra o contacto que esta na posicao 'n'
	encontra_contacto(lista, num, &ant, &actual); 
}
if (actual != NULL)
{
	cont = actual->cont;
	li = cont.n;
	li = li->seguinte;

	if(cont.tipo_utilizador==1)
		printf("preco=0\n");
	else
	{
		while(li)
		{
			cont2 = li->cont2;
			printf("---------------------------\n" );
//percorre as chamadas e calcula a sua soma
			preco=preco+custo_chamada(lista,cont2);

			li = li->seguinte;
		}
		printf("a conta de telefone e' de %0.2f euros\n",preco);
	}
} 
}

//----------------------------------
float custo_chamada(list lista,chamada c)	//calcula o preco de cada chamada
{
float preco;
if(encontra_posicao(lista,c.dest)>0)
{
	return 0;
}
else
{
	if(c.duracao<=60)

		preco=0.50;

	else if(c.duracao>60)

		preco=0.50+ceil((c.duracao-60)/60)*0.2;

	if(c.duracao>6000)
		preco=preco+ceil((c.duracao-6000)/60)*0.1;
}

return preco;
}

//--------------------------------
void ler_dados(list lista)// le os dados de um ficheiro para a lista
{
FILE *registos;
FILE *regista_chamadas;

chamada cont2;
contacto cont;
int pos, n;
list ant;
list actual;
list2 li;

registos = fopen("registos.bin", "rb");

if(registos != NULL)
{
	while(fread(&cont, sizeof(contacto), 1, registos))
	{

		n = encontra_posicao(lista,cont.num_telefone);	

		if(n<0)										
		{
			cont.n = cria_lista2();
			insere_contacto(lista, cont);
		}
	}
}
fclose(registos);

regista_chamadas = fopen("chamadas.bin", "rb");
if(regista_chamadas != NULL)
{
	while(fread(&cont2, sizeof(chamada), 1, regista_chamadas))
	{
		pos = encontra_posicao(lista, cont2.orig);
		if(pos>=0)
		{
			encontra_contacto(lista, pos, &ant, &actual);
			li = actual->cont.n;
			nova_chamada(li, cont2);
		}
	}	
}
fclose(regista_chamadas);
}

//--------------------------------------------------------------------
void gravar_dados(list lista)// grava os dados da lista num ficheiro
{
FILE *registos;
FILE *regista_chamadas;
list2 li;
list l = lista->seguinte;
contacto cont;
chamada cont2;

registos = fopen("registos.bin","wb");
regista_chamadas=fopen("chamadas.bin","wb");

while(l)
{
	cont = l->cont;
	fwrite(&cont , sizeof(cont), 1, registos);
	li=cont.n;
	li=li->seguinte;
	while(li)
	{
		cont2 = li->cont2;
		fwrite(&cont2 , sizeof(cont2), 1, regista_chamadas);
		li=li->seguinte;
	}

	l = l->seguinte;
}

fclose(registos);
fclose(regista_chamadas);

}
//-----------------------------------------------------------------
//funcao do tipo chamada para guardar os dados das chamadas
chamada pede_chamada(char orig[10])
{

chamada p;
strcpy(p.orig,orig);

printf("NUMERO DE TELEFONE de destino :\n");
scanf("%s",&(p.dest));

printf("duracao:(segundos)\n");
scanf("%f", &(p.duracao));

return p;
}

//------------------------------------------------------------------------
//reserva memoria para nova chamda na lista
void nova_chamada(list2 lista, chamada c)	
{
list2 aux;
aux = (list2) malloc (sizeof (n));
if (aux != NULL)
{
	aux->cont2 = c;
	aux->seguinte = lista->seguinte;
	lista->seguinte = aux;
}
}

//-------------------------------------------------------------------
//mostra as chamadas efectuadas por um numero da empresa
void imprime_chamadas(list lista, int n)
{

list ant;
list actual;
contacto cont;
chamada cont2;
list2 li;


if(n >= 0)
{
// encontra o contacto que esta na posicao 'n'
	encontra_contacto(lista, n, &ant, &actual); 
}

if (actual != NULL)
{
	cont = actual->cont;
	li = cont.n;
	li = li->seguinte;

	while(li)
	{
		cont2 = li->cont2;
		printf("---------------------------\n" );
		imprime_chamada(cont2);
		li = li->seguinte;
	}

} 


}
//-------------------------------------------------------------------------
void insere_chamada(list lista, char num[10])
{
int n = encontra_posicao(lista, num);		// encontra a posicao do numero
list ant;
list actual;
contacto cont;
list2 li;

if(n >= 0)
{
// encontra o contacto que esta na posicao 'n'
	encontra_contacto(lista, n, &ant, &actual);
}


if (actual != NULL)		// insere chamadas
{

	cont = actual->cont;
	li = cont.n;
	nova_chamada(li, pede_chamada(num));

} 

}


//------------------------------------------------------------------------
//verifica qual a posicao de um numero na lista e devolve a posicao caso exista
int encontra_posicao(list lista, char num[10])
{
int posicao=0;
contacto cont;
list l = lista->seguinte;

while(l)
{
	cont = l->cont;
	if(strcmp(cont.num_telefone, num) == 0)		// se encontrou o numero
		return posicao;							// sai da funcao e devolve a posicao
	else
	{
		l = l->seguinte;						//senao passa ao seguinte
		posicao++;								// e incrementa a posicao
	}

}

return -1;
}
//----------------------------------------------------------------------
// procura o elemento na posição n da lista
void encontra_contacto(list lista, int n, list *ant, list *actual) 
{
int contador=0;

*ant = lista;
*actual = lista->seguinte;


while ((*actual) != NULL && contador < n) 
// enquanto nao chega ao fim da lista e nao chega a posicao pretendida
{
	*ant = *actual;
	*actual = (*actual)->seguinte;
	contador++; 
}

if ((*actual) != NULL && contador != n)
   *actual = NULL;       /* Se elemento não encontrado*/
}
//----------------------------------------------------------------------

void elimina_contacto(list lista, char num[10])//utiliza as 2 funcoes anteriores 
												// elimina o contacto presente na posicao n da lista
{
int n = encontra_posicao(lista, num);			// encontra a posicao do numero
list ant;
list actual;

if(n >= 0)
{
// encontra o contacto que esta na posicao 'n'
	encontra_contacto(lista, n, &ant, &actual);
}


if (actual != NULL)								// apaga o contacto nessa posicao
{
	ant->seguinte = actual->seguinte;
        free(actual);
} 

}


//-------------------------------------------------------------------
void imprime_contacto(contacto cont){				//imprime dados de um contacto

printf("NUMERO DE TELEFONE: %s\n",cont.num_telefone);
printf("NOME: %s\n",cont.Nome);

printf("TIPO DE UTILIZADOR:");
if(cont.tipo_utilizador==0){
	printf("Funcionario\n");
}
else 
	if(cont.tipo_utilizador==1){
		printf("Gerencia\n");
	}

}

//-------------------------------------------------------------------

void imprime_chamada(chamada cont2){
printf("NUMERO DE TELEFONE: %s\n",cont2.dest);
printf("DURACAO: %f\n",cont2.duracao);
}

//-------------------------------------------------------------------
//imprime todos os contacto da lista caso exista algum

void imprimetudo(list lista)
{
int contador = 1;
contacto cont;
list l = lista->seguinte;
if(l)
{
	printf("---------------------------\n" );

}
else
{
	printf("---------------------------\n" );
	printf("Nenhum telefone na lista\n");
	printf("---------------------------\n" );
}

while(l)
{
	cont = l->cont;
	printf("---------------------------\n" );
	imprime_contacto(cont);
	l = l->seguinte;
	contador++;
}
}



//-------------------------------------------------------------------
//reserva espaco para inserir novo contacto na cabeça da lista
void insere_contacto(list lista, contacto c)	
{
list aux;
aux = (list) malloc (sizeof (NO));
if (aux != NULL)
{
	aux->cont = c;
	aux->seguinte = lista->seguinte;
	lista->seguinte = aux;
}
}

//-------------------------------------------------------------------
contacto novo_telefone(list lista)	// pede os dados para um novo contacto
											// e devolve esse contacto
{

contacto p;
int n,i=0;
int erro=0;
printf("NUMERO DE TELEFONE:\n");
scanf("%s",&(p.num_telefone));
											//condiçoes para verificar se numero é valido
//verifica se o numero ja existe em alguma posiçao na lista
n = encontra_posicao(lista,p.num_telefone);	


if(n>=0)	//se já existir cancelar introduçao de dados
{
	printf("ERRO:numero ja' existe\n");
}

if (strlen(p.num_telefone)!=9)	//se o numero tiver um numero de caracteres != de 9 cancelar introduçao de dados
{
	printf("ERRO:numero invalido\n");
}

if(strlen(p.num_telefone)==9)
		for (i=0;i<strlen(p.num_telefone);i++)
    	if(p.num_telefone[i]<48 || p.num_telefone[i]>57)	//se o numero tiver algum carcter que nao é numero dá erro
	 	{
			erro=1;
			printf("ERRO:caracter inva'lido\n");
	 	}

if(strlen(p.num_telefone)==9 && n<0)
	if (erro==0)
	{
		printf("NOME:\n");
		scanf("%s", &(p.Nome));

		printf("TIPO DE UTILIZADOR:(0)-Funcionario, (1)-Gerencia)\n");
		scanf("%d",&(p.tipo_utilizador));

		p.n = cria_lista2();	//cria uma lista associada ao novo contacto criado
	}
return p;
}

//-------------------------------------------------------------
void menu()	// imprime no ecra o menu de opções
{
printf("---------------------------------------\n" );
printf(" Gestao Telefonica da Empresa Xpto\n");
printf("---------------------------------------\n" );
printf("1 - Inserir novo telefone\n");
printf("2 - Listar telefones\n");
printf("3 - Remover telefone\n");
printf("4 - Inserir nova chamada\n");
printf("5 - Consultar chamadas de telefone\n");
printf("6 - Calcular conta de telefone\n");
printf("7 - Guardar informacao\n" );
printf("8 - Ler informacao\n" );
printf("9 - Sair\n");
printf("---------------------------------------\n" );

}

//--------------------------------------------------------------
list cria_lista(void)	//cria uma lista e devolve essa lista
{
list aux;
aux = (list) malloc (sizeof (NO));
if (aux != NULL)
{
	aux->seguinte = NULL;
}

return aux;
}
//-------------------------------------------------------------
list2 cria_lista2(void)	//cria uma lista e devolve essa lista
							//é criada quando existe um novo contacto
							//serve para guardar a informacao sobre as suas chamdas
{
list2 aux;
aux = (list2) malloc (sizeof (n));
if (aux != NULL)
{
	aux->seguinte = NULL;
}

return aux;
}

Share this post


Link to post
Share on other sites
Briooosa

nop,nao tem erro nenhum,no meu compila e nao tem erros,apenas alguns warnings,mas funciona bem.

quando disse que o programa tinha um problema,nao me referia a erros,mas sim á maneira como foi pensado.

e era apenas na funçao eliminar,na funçao eliminar apenas apago uma parte da lista,funciona na mesma porque quando vou procurar pelo numero ele ja nao existe,mas continua algures em memoria o que ja tinha inserido anteriormente...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.