Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Sign in to follow this  
pedrosimoes

Programa de gerenciamento de oficina! [Duvidas]

Recommended Posts

pedrosimoes

Boas, foi dada pela minha Fac um exercicio em que tinha de criar um programa de gerenciamento de um oficina. O que acontece é que o prof trabalha sempre em Windows e como tenho o meu mbp e nunca tive problemas a programar também não era desta que ia desistir. Logo, o código em que trabalhei foi optimizado para Unix, isto é, aplica-se tanto a Linux como Mac OSX.

Dêem uma vista de olhos no codigo e mandem dicas e ajudem a melhorar o código! :cheesygrin:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//#include <malloc.h>
//#include "stdafx.h"
//#include <windows.h>
//#include <mmsystem.h>

#define MAX_VIATURAS 10
#define MAX_STACK 12

typedef struct viatura
{
char matricula[9];
char proprietario[31];
char marca[16];
char cor[16];
char data_entrada[11];
char estado_reparacao[3];
int tempo_reparacao;
char ocupado;
}VIATURA;

VIATURA *alocar_memoria(int nviaturas)
{
VIATURA *p;

p=(VIATURA *) malloc(sizeof(VIATURA)*nviaturas);
return p;
}
void inicializar(VIATURA *p, int nviaturas)
{
int i;
for (i=0;i<nviaturas;i++)
   	(p++)->ocupado='0';

}
int matricula_valida(char *matricula)
{
	return (isdigit(matricula[0]) && isdigit(matricula[1]) &&
 				matricula[2]=='-' && matricula[5]=='-' &&
			((isdigit(matricula[3]) && isdigit(matricula[4]) &&
			isalpha(matricula[6]) && isalpha(matricula[7])) ||
			(isalpha(matricula[3]) && isalpha(matricula[4]) &&
			isdigit(matricula[6]) && isdigit(matricula[7]))));						
}
char *substring(char *src, int position, int length)
{
char *dest;
dest = (char *) malloc(length*sizeof(char));
dest[0]='\0';
strncat(dest, (src + position), length);
return dest;
}
int data_valida(char *data)
{
int sintax_valida, ano, mes, dia, anobissexto;
int dias_mes[]={31,28,31,30,31,30,31,31,30,31,30,31};

sintax_valida = isdigit(data[0]) && isdigit(data[1]) &&
				isdigit(data[2]) && isdigit(data[3]) && data[4]=='-' &&
				isdigit(data[5]) && isdigit(data[6]) && data[7]=='-' &&
				isdigit(data[8]) && isdigit(data[9]);

if (sintax_valida)
{
	ano = atoi(substring(data, 0,4));
	mes = atoi(substring(data,5,2));
	dia = atoi(substring(data,8,2));
if (!ano || !mes || !dia || mes>12)
	return 0;

anobissexto = (!(ano%4) && (ano%100) || !(ano%400));
if (anobissexto && mes==2)
dias_mes[1]++;

if (dia>dias_mes[mes-1])
return 0;

return 1; //esta tudo correcto

} else
	return 0;
}
int estado_valido (char *estado)
{
return 	!strcmp(estado, "NR") ||
		!strcmp(estado, "RG") ||
		!strcmp(estado, "RL");
}

int transicao_estado_valida(char *estado_antes, char *estado_depois)
{
	return 	(!strcmp(estado_antes, "NR") &&
			(!strcmp(estado_depois, "RG") ||
			!strcmp(estado_depois, "RL"))) ||
			((!strcmp(estado_antes, "RG") &&
			!strcmp(estado_depois, "RL")));
}

void registar_viatura(VIATURA *v, int num_viaturas)
{
int i;
for (i=0;i<num_viaturas && v->ocupado=='1';i++)
		v++;


if(i>= num_viaturas)
	printf("\n\n Todos os lugares da oficina estao ocupados!");
else {
	printf("\nIntroduza os dados na nova viatura\n");

	do {
	printf("Introduza a matricula(Ex:11-11-AA):");
	scanf("%s", v->matricula);
	}while(!matricula_valida(v->matricula));

	do {
	printf("Data de entrada(aaaa-mm-dd):");
	scanf("%s", v->data_entrada);
	} while(!data_valida(v->data_entrada));

	printf("Proprietario:");
	scanf("%s", v->proprietario);
	printf("Marca:");
	scanf("%s", v->marca);
	printf("Cor:");
	scanf("%s", v->cor);

	/* d) Preencher automaticamente campos */
	strcpy(v->estado_reparacao, "NR"); //copia a 2ª string para a 1ª

	v->ocupado='1';
	v->tempo_reparacao = 0;
}
}
void mostrar_viatura(VIATURA *v)
{
printf("\nMatricula: %s", v->matricula);
printf("\nProprietario: %s", v->proprietario);
printf("\nMarca: %s", v->marca);
printf("\nCor: %s", v->cor);
printf("\nData de entrada(aaaa-mm-dd): %s", v->data_entrada);
printf("\nEstado da reparacao: %s", v->estado_reparacao);
printf("\nTempo de reparacao (minutos): %d\n", v->tempo_reparacao);
}
void mostrar_viaturas(VIATURA *v, int num_viaturas)
{
int i;
for (i=0;i<num_viaturas;i++) {
if (v->ocupado=='1')
{
	printf("\n\n[Viatura %d]", i+1);
	mostrar_viatura(v);
}
v++;
getchar();
}

}
void actualizar_estado(VIATURA *v, int num_viaturas)
{
int i;
printf("\nQual o nº do registo da viatura a actualizar?");
scanf("%d",&i);
if (i>0 && i<=num_viaturas && (v+i-1)->ocupado=='1') {
	VIATURA *viatura_actualizar = v+i-1;
	char novo_estado[3];
	/* Mostrar dados da viatura */
	printf("\n[Viatura %d]", i);
	mostrar_viatura(viatura_actualizar);
	/* Ler novo estado de reparacao da viatura até que este seja válido
	e em conjunção com o antigo represente uma transição válida */
	do {
		printf("\nQual o novo estado da viatura?");
		scanf("%s", novo_estado);
}
	while (!estado_valido(novo_estado) ||
			!transicao_estado_valida(viatura_actualizar->estado_reparacao, novo_estado));
	if (!strcmp(viatura_actualizar->estado_reparacao, "NR") &&
	!(strcmp(novo_estado, "RG") ||
	!strcmp(novo_estado, "RL"))) {
/* Inserir tempo de reparacao */
		printf("\nQual o tempo de reparacao:");
		scanf("%d",&viatura_actualizar->tempo_reparacao);
}
if (strcmp(novo_estado, "RL")=='0' &&
	(!strcmp(viatura_actualizar->estado_reparacao,"NR") ||
	!strcmp(viatura_actualizar->estado_reparacao,"RG"))) {
	/* Libertar lugar */
		(viatura_actualizar)->ocupado='0';
}
/* Guardar o novo estado da reparacao */
strcpy(viatura_actualizar->estado_reparacao, novo_estado);
} else
printf("\nO nº de registo introduzido é invalido ou o registo nao esta ocupado!");
}

void troca(VIATURA *a, VIATURA *b)
{
   VIATURA tmp = *a;
   *a = *b;
   *b = tmp;
}
/* a) Ordenar por matricula usando o Método de Seleccao Directa iterativo */
void Seleccao(VIATURA *v, int num_viaturas)
{
int i,j,pos_max;
for(j=num_viaturas-1;j>=0;j--)
{
	pos_max=j;
	for (i=0;i<j;i++)
	{
		if (strcmp(v[i].matricula,v[pos_max].matricula)>0)
			pos_max=i;
	}
troca(&v[j], &v[pos_max]);
}
}
/* b) Ordenar por matricula usando o Método Quicksort iterativo */
void QuickSort_nao_recursivo(VIATURA *t, int num_viaturas)
{
int abaixo, acima, esq, dir, s=0;
VIATURA x;
struct pilha {int l, r;} stack[MAX_STACK];
stack[0].l =0;
stack[0].r =num_viaturas-1;
do { // atende o pedido do topo da lista
	esq=stack[s].l;
	dir=stack[s].r;
	s--;
	do { // parte t[esq] ... t[dir]
		abaixo=esq;
		acima=dir;
		x=t[(esq+dir)/2];
			do {
				while (strcmp(t[abaixo].matricula, x.matricula)<0)
					abaixo++;
				while (strcmp(x.matricula,t[acima].matricula)<0)
					acima--;
				if (abaixo <= acima)
					troca(&t[abaixo],&t[acima]);
				abaixo++;
				acima--;
				}
			while (abaixo <= acima);
			if (abaixo < dir)
			{
// pedido colocado na pilha para ordenar a particao direita
				s++;
				stack[s].l= abaixo;
				stack[s].r= dir;
			}
			dir = acima;
		} while (esq<dir);
	} while (s>=0);
}
/* a) Pesquisa com sequencial sentinela por matricula*/
int Posicao_PesqSent(int num_viaturas, VIATURA chave, VIATURA *v)
{
int i=0;
v[num_viaturas]=chave;
while (strcmp(v[i].matricula,chave.matricula)!=0)
	i+=1;
if (i<num_viaturas)
	return i;
else
	return -1;
}
/* b) Pesquisa binaria => Elementos ordenados */
int PesqBin(VIATURA chave, VIATURA *v,int ind_inf, int ind_sup)
{
int pos, ind_meio;
pos=-1;
while (ind_sup>=ind_inf && pos==-1) {
	ind_meio = (ind_sup+ind_inf)/2;
	if (strcmp(v[ind_meio].matricula,chave.matricula)==0)
		pos=ind_meio;
	else
		if (strcmp(v[ind_meio].matricula,chave.matricula)<0)
		ind_inf = ind_meio+1;
	else
		ind_sup = ind_meio-1;
}
return pos;
}
char MENU()
{
char op;
system("clear");
printf("\n #---------------------------------------------------------#");
printf("\n | (1) Registar viatura |");
printf("\n | (2) Actualizar estado de uma viatura |");
printf("\n | (3) Mostrar todas as viaturas em reparacao |");
printf("\n | (4) Ordenar viaturas (Seleccao directa iterativo) |");
printf("\n | (5) Ordenar viaturas (Quicksort iterativo) |");
printf("\n | (6) Pesquisar viatura (Sequencial Sentinela) |");
printf("\n | (7) Pesquisar viatura (Binaria => Viaturas ordenadas) |");
printf("\n |---------------------------------------------------------|");
printf("\n | (8) Sair |");
printf("\n #---------------------------------------------------------#");
do {
	printf("\nQual a sua opcao: ");
	scanf("%c", &op);
	}
	while (op<'1' || op>'8');
	return op;
}
/* Programa principal */
int main()
{
char opcao;
int posicao_viatura;
VIATURA pesquisa;
VIATURA *viaturas;
viaturas = alocar_memoria(MAX_VIATURAS);
inicializar(viaturas, MAX_VIATURAS);
do {
	opcao = MENU();
	switch(opcao)
		{
			case '1':
			registar_viatura(viaturas, MAX_VIATURAS);
			break;
			case '2':
			actualizar_estado(viaturas, MAX_VIATURAS);
			break;
			case '3':
			mostrar_viaturas(viaturas, MAX_VIATURAS);	
			break;
			case '4':
			Seleccao(viaturas, MAX_VIATURAS);
			printf("\nA lista foi ordenada com sucesso!");
			break;
			case '5':
			QuickSort_nao_recursivo(viaturas, MAX_VIATURAS);
			printf("\nA lista foi ordenada com sucesso!");
			break;
			case '6':
			case '7':
			scanf("%s", pesquisa.matricula);
			//fflush(stdin);
			if (opcao=='6')
				posicao_viatura = Posicao_PesqSent(MAX_VIATURAS, pesquisa, viaturas);
			else
				posicao_viatura = PesqBin(pesquisa, viaturas, 0, MAX_VIATURAS-1);
			if (posicao_viatura == -1)
				printf("\nNao foi encontrada nenhuma viatura com a matricula indicada");
			else
			{
				printf("\nDados da viatura procurada: ");
				printf("\n[Viatura %d]", posicao_viatura+1);
				mostrar_viatura(viaturas+posicao_viatura);
			}
			break;
		}
		fflush(stdin);
		}
		while(opcao!='8');
		return 0;
}

Erros/Bugs encontrados até agora:

Após adicionar uma viatura aparece abaixo do menu duas frases com o mesmo: "Qual a sua opção:"

Se adicionar uma viatura e depois for ver as adicionadas, tenho de carregar cerca de 10 vezes no enter para voltar ao menu principal! Após várias tentativas nao encontrei solução.

Share this post


Link to post
Share on other sites
Localhost

Tens de ter dúvidas mais concretas se queres ser ajudado. Não é postar assim o código. O que é que queres melhorar?


here since 2009

Share this post


Link to post
Share on other sites
pedrosimoes

lol! Para verem o que acontece, é preciso correr o programa. Tal como disse no primeiro post o problema ocorre após inserir uma viatura.

Explicando por passos: Escolho a opção 1 e insiro uma viatura->Volta ao menu e escolho a opção 3, para ver as viaturas inseridas-> Supostamente ao clicar no enter ele volta ao menu, mas não basta 1 "enter", sao precisos cerca de 9 e isso não entendo porque!

Outro problema é quando insiro uma viatura, após o ultimo passo é suposto voltar ao menu e aparecer "Qual a sua opção:". Ocorre tudo mas a frase aparece duas vezes!

Acho que agora fui mais explicito! :cheesygrin:

Share this post


Link to post
Share on other sites
Localhost

Depois de leres.

scanf("%i", &blah);
cleanBuffer(); // Função que limpa
scanf("%i", &lol);


here since 2009

Share this post


Link to post
Share on other sites
pedrosimoes

Hmm, eu pensava que te referias ao

ffllush(stdin);

. Não é o que queres dizer?

Cumps

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
Sign in to follow this  

×

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.