#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
//Constantes
#define USUARIO "root"
#define PASSWORD "7"
#define STRING_CORTO 21
#define STRING_LARGO 42
///////////////////////////////////////////////////////////////////////////////////////////////////
//Declaración de los tipos de variables
//Tipo de dato fecha.
typedef struct
{
int ano, mes, dia, hora, min, seg;
}tipo_fecha;
//Tipo de dato usuario.
typedef struct
{
char login[21], password[21], nombre[21], apellido[42], ext[6];
tipo_fecha ult_reserva;
}tipo_usuario;
//Tipo de dato reserva
typedef struct
{
unsigned short int ocupado;
tipo_usuario usuario;
}tipo_reserva;
///////////////////////////////////////////////////////////////////////////////////////////////////
//OK Inserta en el primer usuario los datos del segundo
void copiar_usuario(tipo_usuario *usuario_d, tipo_usuario *usuario_s)
{
strcpy(usuario_d
->login
,usuario_s
->login
); strcpy(usuario_d
->password
,usuario_s
->password
); strcpy(usuario_d
->nombre
,usuario_s
->nombre
); strcpy(usuario_d
->apellido
,usuario_s
->apellido
); strcpy(usuario_d
->ext
,usuario_s
->ext
); }
//OK Compara dos usuarios, devuelve 0 si no coinciden en nada, 1 si coinciden en login y password, y 2 si coinciden en todo
unsigned short int usuario_cmp(tipo_usuario *usuario1, tipo_usuario *usuario2)
{
if ((strcmp(usuario1
->login
, usuario2
->login
)==0) && (strcmp(usuario1
->password
, usuario2
->password
)==0) && (strcmp(usuario1
->nombre
, usuario2
->nombre
)==0) && (strcmp(usuario1
->apellido
, usuario2
->apellido
)==0) && (strcmp(usuario1
->ext
, usuario2
->ext
)==0)) {printf("2");return 2;} else if (((strcmp(usuario1
->login
,usuario2
->login
)==0) && (strcmp(usuario1
->password
,usuario2
->password
)==0)) || ((strcmp(usuario1
->nombre
,usuario2
->nombre
)==0) && (strcmp(usuario1
->apellido
,usuario2
->apellido
)==0))) return 1; else return 0;
}
//OK Devuelve un 1 si se loguea correctamente como usuario y un 0 si no. Si se loguea el root devuelve 2;
unsigned short int login(tipo_usuario *usuario, tipo_usuario *lista_usuarios)
{
unsigned short int i;
printf("Password %d: ",*(usuario
->nombre
));scanf("%20s",&(usuario
->password
)); if((strcmp(usuario
->login
,USUARIO
)==0) && (strcmp(usuario
->password
,PASSWORD
)==0)) {printf("nLogueado como administradorn"); return 2;} else
{
for(i=0;i<10;i++)
{
if (usuario_cmp(usuario,lista_usuarios+i)==0)
{
copiar_usuario(usuario,(lista_usuarios+i));
printf("Hola %s",(usuario
->nombre
)); return 1;
break;
break;
}
}
return 0;
}
}
//OK Intruce en la matriz de reservas, en la fecha (formato real) una reserva realizada por el usuario.
void reservar(tipo_reserva *matriz_reservas, tipo_fecha *fecha, tipo_usuario *usuario)
{
if (usuario==NULL) (matriz_reservas+13*31*(fecha->mes-1)+13*(fecha->dia-1)+fecha->hora-8)->ocupado=0;
else
{
(matriz_reservas+13*31*(fecha->mes-1)+13*(fecha->dia-1)+fecha->hora-8)->ocupado=1;
copiar_usuario(&((matriz_reservas+13*31*(fecha->mes-1)+13*(fecha->dia-1)+fecha->hora-8)->usuario),usuario);
}
}
//OK Inicializa a cero y luego carga el fichero de datos. El formato del fichero es "mes:dia:hora:nombre:apellidos:"
void inicializar_reservas(tipo_reserva *matriz_reservas)
{
tipo_fecha fecha;
unsigned short int i;
char linea[64],*aux;
tipo_usuario usuario;
for(fecha.mes=0;fecha.mes<12;fecha.mes++)for(fecha.dia=0;fecha.dia<31;fecha.dia++)for(fecha.hora=0;fecha.hora<13;fecha.hora++)
{(matriz_reservas+(31*13)*fecha.mes+13*fecha.dia+fecha.hora)->ocupado=0;}
FILE *archivo_reservas;
archivo_reservas
=fopen("reservas.dat","r"); while(!feof(archivo_reservas
))//Por qué no funciona ftell solo? {
fseek(archivo_reservas
,-1,SEEK_CUR
); fscanf(archivo_reservas
,"%d",&fecha.
mes); fseek(archivo_reservas
,1,SEEK_CUR
); fscanf(archivo_reservas
,"%d",&fecha.
dia); fseek(archivo_reservas
,1,SEEK_CUR
); fscanf(archivo_reservas
,"%d",&fecha.
hora); fseek(archivo_reservas
,1,SEEK_CUR
); fgets(linea
,64,archivo_reservas
); //revisar, hay una forma mejor????
aux=linea;
aux
+=strlen(usuario.
nombre)+1; reservar(matriz_reservas,&fecha,&usuario);
}
}
// Inicializar usuarios. Carga los usuarios del archivo de texto en un array.
void inicializar_usuarios(tipo_usuario *lista_usuarios)
{
unsigned short int i;
char *aux, linea[128];
FILE *archivo_usuarios;
archivo_usuarios
=fopen("usuarios.dat","r"); if (archivo_usuarios
==NULL
) printf("anArchivo de usuarios no encontradon"); else
{
fread(&i
,1,1,archivo_usuarios
); i=(int)i;//????????????????????????Es imprescindible esto??????????????????
lista_usuarios
=(tipo_usuario
*)malloc(i
*sizeof(tipo_usuario
)); i=0;
while(!feof(archivo_usuarios
)) {
//fseek(archivo_usuarios,-1,SEEK_CUR);
fgets(linea
,128,archivo_usuarios
); //login
strcpy((lista_usuarios
+i
)->login
,aux
); //password
aux
=aux
+strlen((lista_usuarios
+i
)->login
)+1; strcpy((lista_usuarios
+i
)->password
,aux
); //nombre
aux
=aux
+strlen((lista_usuarios
+i
)->password
)+1; strcpy((lista_usuarios
+i
)->nombre
,aux
); //apellido
aux
=aux
+strlen((lista_usuarios
+i
)->nombre
)+1; strcpy((lista_usuarios
+i
)->apellido
,aux
); //extensión
aux
=aux
+strlen((lista_usuarios
+i
)->apellido
)+1; strcpy((lista_usuarios
+i
)->ext
,aux
); printf("%sn",(lista_usuarios
+i
)->apellido
); i++;
}
}
}
//OK Guarda las reservas en reservas.dat
void guardar(tipo_reserva *matriz_reservas)
{
unsigned short int hora,dia,mes;
FILE *archivo_reservas;
archivo_reservas
=fopen("reservas.dat","w"); for(mes=0;mes<12;mes++)for(dia=0;dia<31;dia++)for(hora=0;hora<13;hora++)if((matriz_reservas+(31*13)*mes+13*dia+hora)->ocupado==1)
{
fprintf(archivo_reservas
,"%d:%d:%d:%s:%s:n",mes
+1,dia
+1,hora
+8, (matriz_reservas+(31*13)*mes+13*dia+hora)->usuario.nombre,(matriz_reservas+(31*13)*mes+13*dia+hora)->usuario.apellido);
}
}
//OK Muestra el menú en pantalla y devuelve el int opción
unsigned short int menu()
{
unsigned short int opcion;
printf("n1 - Introduccion de datos personalesn"); printf("2 - Consulta de reservas por mesn"); printf("3 - Consulta de reservas del usuarion"); printf("4 - Creacion de reservasn"); printf("5 - Borrado de reservasn"); printf("6 - Volver al menu inicialn"); return opcion;
}
//OK Introduce usuario. Ahora es inútil. Dejo el código por si me fuese útil posteriormente.
void introducir_datos(tipo_usuario *usuario)
{
printf("nSus apellidos: ");gets(usuario
->apellido
); printf("nSu extensión telefónica: ");gets(usuario
->ext
); }
//OK Saca por pantalla una fecha de la matriz_reserva, y muestra si está ocupada o libre
void imprimir_reserva(tipo_reserva *matriz_reservas, tipo_fecha *fecha)
{
if ((matriz_reservas+13*31*(fecha->mes-1)+13*(fecha->dia-1)+fecha->hora-8)->ocupado==1)
{
printf("nEl dia %d del mes %d a las %d la sala ha sido reservada por %s %sn", fecha->dia,fecha->mes,fecha->hora,(matriz_reservas+13*31*(fecha->mes-1)+13*(fecha->dia-1)+fecha->hora-8)->usuario.nombre,
(matriz_reservas+13*31*(fecha->mes-1)+13*(fecha->dia-1)+fecha->hora-8)->usuario.apellido);
}
else printf("nEl dia %d del mes %d a las %d el aula está libren",fecha
->dia
,fecha
->mes
,fecha
->hora
); }
//OK Presenta en pantalla las reservas de un mes o de un usuario
void consultar_reservas(tipo_reserva *matriz_reservas, tipo_usuario *usuario)
{
tipo_fecha fecha;
int numero;
numero=0;
if (usuario==NULL)
{
while(1)
{
printf("nNumero del mes a consultar: "); if ((fecha.
mes>12) || (fecha.
mes<1)) printf("nNumero de mes no valido.n"); else break;
}
for(fecha.dia=1;fecha.dia<32;fecha.dia++)for(fecha.hora=8;fecha.hora<21;fecha.hora++)
{
if ((matriz_reservas+(13*31*(fecha.mes-1))+(13*(fecha.dia-1))+(fecha.hora-8))->ocupado!=0)
{
imprimir_reserva(matriz_reservas, &fecha);
numero++;
}
}
}
else
{
for(fecha.mes=1;fecha.mes<13;fecha.mes++)for(fecha.dia=1;fecha.dia<32;fecha.dia++)for(fecha.hora=8;fecha.hora<21;fecha.hora++)
if (((matriz_reservas+(13*31*(fecha.mes-1))+(13*(fecha.dia-1))+(fecha.hora-8))->ocupado!=0) &&
(usuario_cmp(&((matriz_reservas+(13*31*(fecha.mes-1))+(13*(fecha.dia-1))+(fecha.hora-8))->usuario),usuario)>0))
{
imprimir_reserva(matriz_reservas, &fecha);
numero++;
}
}
if(usuario
!=NULL
) printf("nEl usuario actual ha realizado %d reservasn",numero
); else printf("nHay %d reservas en el mes %dn",numero
,fecha.
mes); }
//OK Funcion para comprobar que una fecha tiene un formato correcto
unsigned short int validar_fecha(tipo_fecha f)
{
unsigned short int valida=1;
//Compruebo si la fecha "existe"
if ((f.dia<1 || f.dia>31 || f.mes>12 || f.mes<1) || (f.hora<8 || f.hora>20)) valida=0;
else
{
if (f.mes==2)
{
if (f.dia>29) valida=0;
else if (((f.ano%4!=0) || ((f.ano%100==0) && (f.ano%400!=0))) && (f.dia>28)) valida=0;
}
else
{
if (f.mes%2==0)
{
if ((f.mes<=7) && (f.dia>30)) valida=0;
}
else if ((f.mes>8) && (f.dia>30)) valida=0;
}
}
//Compruebo que la fecha sea mayor que el momento actual;
if (valida==1)
{
struct tm *ahora;
if ( ahora->tm_mon+1>f.mes ||
(ahora->tm_mon+1==f.mes && ahora->tm_mday>f.dia) ||
(ahora->tm_mon+1==f.mes && ahora->tm_mday==f.dia && ahora->tm_hour>f.hora)) valida=0;
}
return valida;
}
//OK Crear reserva
void tratar_reserva(tipo_reserva *matriz_reservas, tipo_usuario *usuario, int opcion)
{
tipo_fecha fecha, fecha1, fecha2;
//Cambiar esto para usar la librería time.h
fecha.ano=2009;
char confirmacion;
unsigned short int contador=0;
do
{
printf("nDatos de la reserva:n Mes: ");scanf("%d",&fecha1.
mes); printf(" Horas de la reserva (de 8 a 21)n hora de inicio: ");scanf("%d",&fecha1.
hora); fecha2=fecha;
printf(" hora de finalizacion: ");scanf("%d",&fecha2.
hora); if (validar_fecha(fecha1) && (fecha2.hora<22) && (fecha2.hora>=fecha1.hora)) break;
else printf("anFecha y/u hora incorrectasn"); }while(1);
fecha=fecha1;
//Comprobar si las horas están ocupadas o no
if (opcion==1) contador=fecha2.hora-fecha1.hora;
do
{
if ((opcion*(matriz_reservas+13*31*(fecha.mes-1)+13*(fecha.dia-1)+fecha.hora-8)->ocupado)==1) contador--;
else if (usuario_cmp(&((matriz_reservas+13*31*(fecha.mes-1)+13*(fecha.dia-1)+fecha.hora-8)->usuario),usuario)>0) contador++;
imprimir_reserva(matriz_reservas,&(fecha));
fecha.hora++;
}while(fecha.hora<fecha2.hora);
fecha=fecha1;
if (!contador>0)
if(opcion
==1) printf("nHoras no disponiblesn"); else printf("No ha realizado ninguna reserva en estas horas"); if (contador>0)
{
if(opcion==1)
{
printf("nEstán disponibles %d de las %d horas que ha solicitado.nRealizar la reserva? (S/N): ",contador
,fecha2.
hora-fecha1.
hora); scanf("%s",&confirmacion
); if ((strcmp(&confirmacion
,"S")==0) || (strcmp(&confirmacion
,"s")==0)) {
time_t segundos;
struct tm *ahora;
//Esto es uan chapuza, hay que cambiar el tipo fecha por el estándar de time;
usuario->ult_reserva.ano=ahora->tm_year;
usuario->ult_reserva.mes=ahora->tm_mon;
usuario->ult_reserva.dia=ahora->tm_mday;
usuario->ult_reserva.hora=ahora->tm_hour;
usuario->ult_reserva.min=ahora->tm_min;
usuario->ult_reserva.seg=ahora->tm_sec;
do
{
reservar(matriz_reservas, &fecha, usuario);
imprimir_reserva(matriz_reservas, &fecha);
fecha.hora++;
}while(fecha.hora<fecha2.hora);
}
else printf("nReserva no realizadan"); }
if(opcion==0)
{
printf("nPueden borrarse %d de las %d horas que ha solicitado.nRealizar la reserva? (S/N): ",contador
,fecha2.
hora-fecha1.
hora); scanf("%s",&confirmacion
); if ((strcmp(&confirmacion
,"S")==0) || (strcmp(&confirmacion
,"s")==0)) {
do
{
reservar(matriz_reservas, &fecha, NULL);
imprimir_reserva(matriz_reservas, &fecha);
fecha.hora++;
}while(fecha.hora<fecha2.hora);
printf("nBorrado realizadon"); }
else printf("nBorrado no realizadon"); }
}
}
///////////////////////////////////////////////////////////////////////////////
int main()
{
//Declaración de las variables
unsigned short int mes,dia,hora;
char opcion,confirmacion;
char nombre[STRING_CORTO], password[STRING_CORTO];
tipo_usuario usuario, *lista_usuarios;
tipo_fecha fecha;
//los índices de los arrays: mes,dia,hora
tipo_reserva matriz_reservas[122][31][13];
inicializar_reservas(&(matriz_reservas[0][0][0]));
inicializar_usuarios(lista_usuarios);
do
{
printf("nEscoja una opcion:n"); printf("n1 - Loguearsen2 - Salirn"); if (opcion==1)
{
log=login
(&usuario
,lista_usuarios
); do
{
switch(opcion)
{
case 1: introducir_datos(&usuario);break;
case 2: consultar_reservas(&(matriz_reservas[0][0][0]),NULL);break;
case 3: consultar_reservas(&(matriz_reservas[0][0][0]),&usuario);break;
case 4: tratar_reserva(&(matriz_reservas[0][0][0]),&usuario,1);break;
case 5: tratar_reserva(&(matriz_reservas[0][0][0]),&usuario,0);break;
case 6: usuario.nombre[0]=0;usuario.apellido[0]=0;guardar(&(matriz_reservas[0][0][0]));break;
default: printf("anOpcion incorrectan");break; }
}while(opcion!=6);
}
else if (opcion==2) break;
else printf("anOpcion incorrectan"); }while(1);
printf("nFIN DEL PROGRAMAnn"); }