/*
Taller #5
Autores: Juan David Roman - Sebastian Rivas Rubio
Fecha: 06/11/2023
*/
// Inclusion de librerias
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <locale.h>
#include <conio.h>
#include <windows.h>
// Macros
#define SONIDO "\7"
#define BEEP printf(SONIDO)
#define LIMPIAPANTALLA system("cls")
#define FONDOPANTALLA system("color F3")
#define PAUSA system("pause")
#define NDTO 100
#define ANIOACTUAL 2023
#define BISIESTO(Anio) (Anio % 4 == 0 && Anio % 100 != 0 || Anio % 400 == 0)
#define FINCADENA '\0'
#define SALTOLINEA(N) { for (int i = 0; i < N; i++) printf("\n"); }
#define ENTER 13
#define SPACE ''
// Definicion de tipos propios
typedef unsigned short int usi;
typedef enum Meses {Enero = 1, Febrero, Marzo, Abril, Mayo, Junio, Julio, Agosto,
Septiembre, Octubre, Noviembre, Diciembre};
typedef enum Colores {Blanco=1, Negro, Plateado, Militar, Desconocido};
typedef enum TiposSubmarinos {Convencional=1, Semielectrico, Propulsionnuclear,
SubDesconocido};
typedef enum OpcionesMenu{Agregar = 1, Enlistar, ImprimirEstadisticas, Salir};
typedef enum TipoEntrada {Letras, Digitos, Todo};
// Definicion de vectores auxiliares de trabajo
const char *NomMes[] = {"No permitido", "Enero", "Febrero", "Marzo", "Abril", "Mayo",
"Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"};
const char *NomColor[] = {"No permitido", "Blanco", "Negro", "Plateado", "Militar",
"Desconocido"};
const char *NomTipoSub[] = {"No permitido", "Convencional", "Semielectrico",
"Propulsionnuclear", "SubDesconocido"};
/* -- Funciones de validacion auxiliares -- */
// Funcion para validar las cadenas de texto
/*usi LeerTexto(char Cadena[], TipoEntrada Tipo, usi LongCadena) {
char Car;
usi NroCarLeidos = 0;
while (((Car = toupper(getche())) != ENTER) && NroCarLeidos < LongCadena) {
switch (Tipo) {
case Letras:
if (isalpha(Car) || (isspace(Car) == SPACE))
Cadena[NroCarLeidos++] = toupper(Car);
break;
case Digitos:
if (isdigit(Car))
Cadena[NroCarLeidos++] = toupper(Car);
else BEEP;
break;
case Todo:
Cadena[NroCarLeidos++] = toupper(Car);
break;
}
}
if (Car == ENTER) Cadena[NroCarLeidos++] = '\n';
Cadena[NroCarLeidos] = FINCADENA;
printf ("\n");
return NroCarLeidos;
}*/
// Funcion para asignar el dia maximo del mes
int DiaMaxMes(int Aniolanzamiento, Meses Mes) {
int DiaMax;
switch (Mes) {
case Enero :
case Marzo :
case Mayo :
case Julio :
case Agosto :
case Octubre :
case Diciembre : DiaMax = 31;
break;
case Febrero : DiaMax = 28;
if (BISIESTO(Aniolanzamiento)) {
DiaMax = 29;
break;
}
case Abril :
case Junio :
case Septiembre :
case Noviembre : DiaMax = 30;
break;
}
return DiaMax;
}
// Funcion para validar la sumergibilidad
float LeeSumergibilidadValida() {
float SumergibilidadValida;
while (1) {
scanf("%f", &SumergibilidadValida);
if (SumergibilidadValida > 0) return SumergibilidadValida;
BEEP;
printf(" *** AVISO: sumergibilidad no valida, debe de ser un valor mayor a 0
***");
printf("\n Sumergibilidad: ");
}
}
// Funcion para validar el numero de dormitorios
int LeeDormitoriosValido() {
int DormitoriosValido;
while (1) {
scanf("%d", &DormitoriosValido);
if (DormitoriosValido > 0) return DormitoriosValido;
BEEP;
printf(" *** AVISO: dormitorios no valido, debe de ser un valor mayor a 0 ***");
printf("\n Dormitorios: ");
}
}
// Funcion para validar la capacidad de la tripulacion
int LeeCapacidadValida() {
int CapacidadValida;
while (1) {
scanf("%d", &CapacidadValida);
if (CapacidadValida > 0) return CapacidadValida;
BEEP;
printf("*** AVISO: capacidad de la tripulacion no valida, debe de ser un valor mayor a
0 ***");
printf("\nCapacidad de tripulacion: ");
}
}
// Funcion para validar el tipo de submarino
TiposSubmarinos LeeTipoSubValido() {
int TipoSubValido;
while (1) {
scanf("%d", &TipoSubValido);
if (TipoSubValido >= Blanco && TipoSubValido <= Desconocido) return
(TiposSubmarinos)TipoSubValido;
BEEP;
printf(" *** AVISO: tipo de submarino no valido ***");
printf("\n Tipos de submarino:\n 1 - Convencional\n 2 - Semielectrico\n 3 -
Propulsion nuclear");
printf("\n Seleccione una opcion: ");
}
}
// Funcion para validar el anio
int LeeAnioValido() {
int AnioValido;
while(1) {
scanf("%u", &AnioValido);
if (AnioValido <= ANIOACTUAL) return AnioValido;
BEEP;
printf(" *** AVISO: Anio no valido ***");
printf("\n Anio de creacion: ");
}
}
// Funcion para validar el mes
Meses LeeMesValido() {
Meses MesValido;
while(1) {
scanf("%u", &MesValido);
if (MesValido >= Enero && MesValido <= Diciembre) return MesValido;
BEEP;
printf(" *** AVISO: Mes no valido ***");
printf("\n Mes de creacion: ");
}
}
// Funcion para validar el anio
int LeeDiaValido(int Anio, Meses Mes) {
int DiaValido;
while(1) {
scanf("%u", &DiaValido);
if (DiaValido >= 1 && DiaValido <= DiaMaxMes(Anio, Mes)) return DiaValido;
BEEP;
printf(" *** Error: Dia invalido para el mes de %s ***", NomMes[Mes]);
printf("\n Dia de creacion: ");
}
}
// Funcion para validar la sumergibilidad
float LeePesoValido() {
float PesoValido;
while (1) {
scanf("%f", &PesoValido);
if (PesoValido > 0) return PesoValido;
BEEP;
printf(" *** AVISO: peso no valido, debe de ser un valor mayor a 0
***");
printf("\n Peso: ");
}
}
// Funcion para validar el color
Colores LeeColorValido() {
int ColorValido;
while (1) {
scanf("%d", &ColorValido);
if (ColorValido >= Blanco && ColorValido <= Desconocido) return
(Colores)ColorValido;
BEEP;
printf(" *** AVISO: Color no valido ***");
printf("\n Color del Submarino:\n 1 - Blanco\n 2 - Negro\n 3 - Plateado\n 4
- Militar\n 5 - Desconocido");
printf("\n Seleccione un color: ");
}
}
/* ---------------------------------------- */
/* -- Funciones principales auxiliares -- */
// Funcion para el menu principal
OpcionesMenu ImprimirMenu() {
int opcion;
LIMPIAPANTALLA;
printf("\nSeleccione una Opcion:\n 1-Insertar otro Submarino\n 2-Enlistar
Submarinos\n 3-Imprimir Estadisticas\n 4-Salir\n");
printf("\nSeleccione: ");
scanf("%d", (int*)&opcion);
return (OpcionesMenu)opcion;
}
// Funcion para Ingresar un Submarino
usi ingresarDatosSubmarino(float SumergibilidadAgregar[NDTO], int
DormitoriosAgregar[NDTO], int CapacidadTripulacionAgregar[NDTO], Colores
ColorSubmarinoAgregar[NDTO], TiposSubmarinos TipoSubmarinoAgregar[NDTO], usi
DiaCreacionAgregar[NDTO], Meses MesCreacionAgregar[NDTO], usi
AnioCreacionAgregar[NDTO], float PesoAgregar[NDTO], char ModeloAgregar[NDTO][30],
char MarcaAgregar[NDTO][20], int ContadorTiposSubAgregar[NDTO], int
ContadorColoresAgregar[NDTO], int N) {
usi NN = N;
char Decision;
do {
printf("\n-------- Ingrese los Datos del Submarino --------\n");
printf(" Sumergibilidad: "); SumergibilidadAgregar[NN] =
LeeSumergibilidadValida();
printf("\n Dormitorios: "); DormitoriosAgregar[NN] = LeeDormitoriosValido();
printf("\nCapacidad de tripulacion: "); CapacidadTripulacionAgregar[NN] =
LeeCapacidadValida();
//printf("\n Modelo del submarino: "); LeerTexto(ModeloAgregar[NN], Todo, 30);
printf("\n Modelo del submarino: ");scanf("%s", ModeloAgregar[NN]);
printf("\n Tipos de submarino:\n 1 - Convencional\n 2 - Semielectrico\n 3 -
Propulsion nuclear\n");
printf("\n Seleccione una opcion: "); TipoSubmarinoAgregar[NN] =
LeeTipoSubValido();
printf("\n Anio de creacion: "); AnioCreacionAgregar [NN] = LeeAnioValido();
printf("\n Mes de creacion: "); MesCreacionAgregar [NN] = LeeMesValido();
printf("\n Dia de creacion: "); DiaCreacionAgregar [NN] =
LeeDiaValido(AnioCreacionAgregar[NN], MesCreacionAgregar[NN]);
printf("\n Peso: "); PesoAgregar[NN] = LeePesoValido();
//printf("\n Marca: "); LeerTexto(MarcaAgregar[NN], Letras, 20);
printf("\n Marca: ");scanf("%s", MarcaAgregar[NN]);
printf("\n Color del Submarino:\n 1 - Blanco\n 2 - Negro\n 3 - Plateado\n 4
- Militar\n 5 - Desconocido\n");
printf("\n Seleccione un color: "); ColorSubmarinoAgregar[NN] =
LeeColorValido();
ContadorTiposSubAgregar[TipoSubmarinoAgregar[NN]]++;
ContadorColoresAgregar[ColorSubmarinoAgregar[NN]]++;
NN ++;
printf("\n\n Desea ingresar otro Submarino?: S/N \n\n"); scanf("%c", &Decision);
} while (toupper(Decision) == 'S' && NN < NDTO);
return NN;
}
// Funcion para enlistar los Submarinos
void enlistarSubmarinos(float SumergibilidadEnlistar[NDTO], int
DormitoriosEnlistar[NDTO], int CapacidadTripulacionEnlistar[NDTO], Colores
ColorSubmarinoEnlistar[NDTO], TiposSubmarinos TipoSubmarinoEnlistar[NDTO], usi
DiaCreacionEnlistar[NDTO], Meses MesCreacionEnlistar[NDTO], usi
AnioCreacionEnlistar[NDTO], float PesoEnlistar[NDTO], char ModeloEnlistar[NDTO][30],
char MarcaEnlistar[NDTO][20], int N) {
FONDOPANTALLA;
LIMPIAPANTALLA;
if (N == 0) {
BEEP;
printf("AVISO: No hay datos para imprimir \n\n");
PAUSA;
return;
}
for (int i = 0; i < N; i++) {
printf("\n\n-------- Impresion de Datos del Submarino: %d --------\n\n", i + 1);
printf(" Sumergibilidad: %f\n", SumergibilidadEnlistar[i]);
printf("\n Dormitorios: %d\n", DormitoriosEnlistar[i]);
printf("\nCapacidad de tripulacion: %d\n", CapacidadTripulacionEnlistar[i]);
printf("\n Modelo del submarino: %s\n", ModeloEnlistar[i]);
printf("\n Tipo de Submarino: %s\n", NomTipoSub[TipoSubmarinoEnlistar[i]]);
printf("\n Fecha de creacion: %hu/%d/%hu\n", DiaCreacionEnlistar[i],
MesCreacionEnlistar[i], AnioCreacionEnlistar[i]);
printf("\n Peso: %f\n", PesoEnlistar[i]);
printf("\n Marca: %s\n", MarcaEnlistar[i]);
printf("\n Color: %s\n", NomColor[ColorSubmarinoEnlistar[i]]);
printf("\n\n----- oprima la tecla <ENTER> para el siguiente dato -----\n");
PAUSA;
}
}
// Funcion para enlistar las Estadisticas
void enlistarEstadisticas(int ContadorTiposSub[], int ContadorColores[], usi N) {
FONDOPANTALLA;
LIMPIAPANTALLA;
if (N == 0) {
BEEP;
printf("AVISO: \t\n No hay datos para imprimir estadisticas \n\n");
PAUSA;
return;
}
printf("\n|------------------ Estadisticas de los submarinos ------------------|\n");
// Tipos de Submarino
for (int i = 1; i < 4; i++) {
printf(" %s: %u\n", NomTipoSub[i], ContadorTiposSub[i]);
}
printf("\n\n");
// Colores
for (int i = 1; i < 5; i++) {
printf(" %s: %u\n", NomColor[i], ContadorColores[i]);
}
printf("\n|--------------------------------------------------------------------|\n");
}
/* ------------------------------------- */
// Funcion principal
int main() {
// Declaracion de variables
float Sumergibilidad [NDTO];
float Peso [NDTO];
int Dormitorios [NDTO];
int CapacidadTripulacion [NDTO];
Colores ColorSubmarino [NDTO];
TiposSubmarinos TipoSubmarino [NDTO];
usi DiaCreacion [NDTO]; //
Meses MesCreacion [NDTO]; //
usi AnioCreacion [NDTO]; //
char Modelo [NDTO][30];
char Marca [NDTO][20];
OpcionesMenu Opcion; //
// Declaracion de contadores
int ContadorTiposSub [4] = {0, 0, 0, 0};
int ContadorColores [5] = {0, 0, 0, 0, 0};
// Control de Datos
usi N = 0;
do {
Opcion = ImprimirMenu();
switch (Opcion) {
case Agregar:
// Insercion de Datos
N = ingresarDatosSubmarino(Sumergibilidad, Dormitorios,
CapacidadTripulacion, ColorSubmarino, TipoSubmarino, DiaCreacion, MesCreacion,
AnioCreacion, Peso, Modelo, Marca, ContadorTiposSub, ContadorColores, N);
break;
case Enlistar:
// Impresion de Datos
enlistarSubmarinos(Sumergibilidad, Dormitorios, CapacidadTripulacion,
ColorSubmarino, TipoSubmarino, DiaCreacion, MesCreacion, AnioCreacion, Peso, Modelo,
Marca, N);
break;
case ImprimirEstadisticas:
// Estadisticas de cada Enumerado
enlistarEstadisticas(ContadorTiposSub, ContadorColores, N);
break;
case Salir:
FONDOPANTALLA;
printf("Saliendo del programa.\n");
PAUSA;
break;
default:
printf("Opcion no valida. Intente de nuevo.\n");
PAUSA;
}
} while (Opcion != Salir);
return(0);
}