Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

pedrosimoes

Programa de gerenciamento de oficina! [Duvidas]

Mensagens Recomendadas

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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:

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.