restricción de fecha enc++

Iniciado por juligarc10, 10 Diciembre 2018, 17:43 PM

0 Miembros y 1 Visitante están viendo este tema.

juligarc10

Hola amigos.

Necesito ayudar urgente, ya que non consigo que esta parte del programa me funcione. Esta parte del programa intenta hacer que por ejemplo en año bisiesto te permita introducir hasta 29 dias, pero en año no bisiesto hasta 28. O por ejemplo que si metes la fecha 2/13/2018 te vuelva a pedir la fecha; entre otras cosas... El problema es que no cumple su función tal y como debería, por ejemplo si introduces la fecha 31/4/2000, el programa creee que es valida, cuando no debería. Echenle un vistazo por favor. Aqui les dejo la parte del codigo que falla. El codigo compila. Un saludo.

do{variosClientes.Clientes[variosClientes.numClientes].fecha.dia=leerEntero("Fecha\n dia");
    variosClientes.Clientes[variosClientes.numClientes].fecha.mes=leerEntero("Fecha\n mes");
    variosClientes.Clientes[variosClientes.numClientes].fecha.anho=leerEntero("Fecha\n anho");
    a=variosClientes.Clientes[variosClientes.numClientes].fecha.anho;
    b=variosClientes.Clientes[variosClientes.numClientes].fecha.mes;
    c=variosClientes.Clientes[variosClientes.numClientes].fecha.anho;
if ((a % 4 == 0) && (a % 100 != 0 || a % 400 == 0)&&(b==2)&&((a>29)||(a<1))){ //febrero en año bisiesto
        x=true;
        break;}
    if ((b==1||b==3||b==5||b==7||b==8||b==10||b==12)&&(a>31||a<1)){ //meses con 31 dias
        x=true;
        break;}
    if ((b==4||b==6||b==9||b==11)&&(a>30||a<0)){ //meses con 30 dias
        x=true;
        break;}
    if (b<1||b>12){ //meses inexistente
        x=true;
        break;}
    if ((b==2)&&(a<1||a>28)&&(a % 4 != 0)){//febrero en año no bisiesto
        x=true;
        break;}
}while (x);

Beginner Web

#1
Hola muchacho, puedes usar esta funcion que acabo de hacer recien para ti  ;-)
Código (cpp) [Seleccionar]
#include <iostream>
#include <stdlib.h>

typedef struct tfecha{
int dia;
int mes;
int anyo;
};

bool validar_fecha(tfecha fecha)
{
switch(fecha.mes){
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
if(fecha.dia>0 && fecha.dia<32)
return true;
else
return false;
break;
case 4: case 6: case 9: case 11:
if(fecha.dia>0 && fecha.dia<31)
return true;
else
return false;
break;
case 2: if(fecha.anyo%4==0){
if(fecha.dia>0 && fecha.dia<30)
return true;
else
return false;
}
else{
if(fecha.dia>0 && fecha.dia<29)
return true;
else
return false;
}
break;
default: return false;
}
}

int main()
{
tfecha fecha;
do{
cout<<"Ingrese dia: ";
cin>>fecha.dia;
cout<<"Ingrese mes: ";
cin>>fecha.mes;
cout<<"Ingrese año: ";
cin>>fecha.anyo;
}while(validar_fecha(fecha)==false);
cout<<"Fecha: "<<fecha.dia<<"/"<<fecha.mes<<"/"<<fecha.anyo<<endl;
system("pause");
}

PD: No se hacen tareas, esto es solo un mini ejemplo
7w7

K-YreX

Te recomiendo encapsular todas esas comprobaciones en una o varias funciones para tener un código más legible.
Código (cpp) [Seleccionar]

bool fechaValida(const int day, const int month, const int year){
   bool valido = true;
   int limiteFebrero = diasFebrero(year); // devuelve 29 si es bisiesto, 28 si no lo es
   if(month < 1 || month > 12 || day < 1 || day > 31) // condiciones que no dependen de nada, se salen de los limites
       valido = false;
   else if(month == 2 && day > limiteFebrero) // condiciones que dependen de que que sea bisiesto
       valido = false;
   else if(mes30Dias(month) && day == 31) //condiciones para los meses de 30 dias
       valido = false;
   return valido;
}


Usando <if else> que es más recomendable que usar <break> no tienes que comprobar una condición que ya se ha evaluado antes ya que si entra en un <else if> es porque no ha entrado en un <if> anterior.

Te he dejado un ejemplo de como podría quedar mejor encapsulado. Yo creo que así es más legible. Además esa es una función que puedes usar siempre que trabajes con fechas por lo que viene bien tenerlo en una función. Ahora te queda completar las funciones que he usado ahí y que no están implementadas.

Creo que no me he dejado ninguna comprobación. De ser así podéis comentármelo.  :-X
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

K-YreX

Citar
case 2: if(fecha.anyo%4==0)
Un año no es bisiesto porque sea divisible por 4 únicamente.

Citar
Desde un enfoque algorítmico, se consideran las proposiciones o enunciados lógicos siguientes:

p: Es divisible entre 4
q: Es divisible entre 100
r: Es divisible entre 400
Entonces se utiliza la fórmula lógica <p && (!q || r)> para establecer si un año dado es bisiesto: es bisiesto si es divisible entre cuatro y (no es divisible entre 100 ó es divisible entre 400).
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

AlbertoBSD

#4
Se podria dejar en una sola funcion:

#include<stdio.h>
#include<stdbool.h>

bool fechaValida(const int day, const int month, const int year);

int main() {
if(fechaValida(29,2,2004)) {
printf("Fecha Valida\n");
}
else {
printf("Fecha NO Valida\n");
}
}

bool fechaValida(const int day, const int month, const int year){
int dias_mes[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
bool valido = true;
if(year % 4 == 0)
dias_mes[1] = 29;
if(month < 1 || month > 12 || day < 1 || day > dias_mes[month-1]) //Unica condicion
valido = false;
return valido;
}
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

K-YreX

Bastante más sencillo al usar los arrays para los días, es cierto. Lo único como he comentado antes, cambiando la condición de que sea bisiesto, ya que ese código no es cierto.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

AlbertoBSD

#6
Jajajaja tengo que ver bien lo de los años bisiestos, mientras tanto segun tu enunciado quedaria asi no?

bool fechaValida(const int day, const int month, const int year){
int dias_mes[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
bool valido = true;
if(year % 4 == 0 && (!(year % 100 == 0) || (year % 400 == 0) ))
dias_mes[1] = 29;
if(month < 1 || month > 12 || day < 1 || day > dias_mes[month-1]) //Unica condicion
valido = false;
return valido;
}
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

K-YreX

Exacto, además me estaba dando cuenta también de que usar dos arrays para solo cambiar un valor de podía cambiar ese valor en la condición, pero veo que te has adelantado  :xD
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

juligarc10

Cita de: Beginner Web en 10 Diciembre 2018, 17:53 PM
Hola muchacho, puedes usar esta funcion que acabo de hacer recien para ti  ;-)
Código (cpp) [Seleccionar]
#include <iostream>
#include <stdlib.h>

typedef struct tfecha{
int dia;
int mes;
int anyo;
};

bool validar_fecha(tfecha fecha)
{
switch(fecha.mes){
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
if(fecha.dia>0 && fecha.dia<32)
return true;
else
return false;
break;
case 4: case 6: case 9: case 11:
if(fecha.dia>0 && fecha.dia<31)
return true;
else
return false;
break;
case 2: if(fecha.anyo%4==0){
if(fecha.dia>0 && fecha.dia<30)
return true;
else
return false;
}
else{
if(fecha.dia>0 && fecha.dia<29)
return true;
else
return false;
}
break;
default: return false;
}
}

int main()
{
tfecha fecha;
do{
cout<<"Ingrese dia: ";
cin>>fecha.dia;
cout<<"Ingrese mes: ";
cin>>fecha.mes;
cout<<"Ingrese año: ";
cin>>fecha.anyo;
}while(validar_fecha(fecha)==false);
cout<<"Fecha: "<<fecha.dia<<"/"<<fecha.mes<<"/"<<fecha.anyo<<endl;
system("pause");
}

PD: No se hacen tareas, esto es solo un mini ejemplo

Muchos gracias. Me ha servido perfectamente. Aunque como creo que te han comentado por abajo el año bisiesto no se determina por esto solamente, (año%4==0), sino que depende de estas condiciones (año%4==0)&& (año% 100 != 0 || caño% 400 == 0).

Gracias y un saludo.

Beginner Web

Hola, perdon que venga a hacer spam pero queria saber si este TAD Fecha esta bien/se le puede mejorar las operaciones que tiene, me gusto la forma en la que AlbertoBSB validó  la fecha con esa función ;)
Código (cpp) [Seleccionar]
#include <iostream>
#include <stdlib.h>

using namespace std;

typedef struct tfecha{
int dia;
int mes;
int anyo;
};

void crear_fecha(tfecha &fecha);
bool validar_fecha(tfecha fecha);
void igualdad_fechas(tfecha a, tfecha b);
void comparar_fechas(tfecha a, tfecha b);
bool bisiesto(tfecha fecha);
void dias(tfecha fecha);
void mostrar_mes(tfecha fecha);
void mostrar_fecha(tfecha fecha);

int main()
{
tfecha a, b;
crear_fecha(a);
crear_fecha(b);
igualdad_fechas(a,b);
comparar_fechas(a,b);
if(bisiesto(a)==true)
cout<<"Año bisiesto"<<endl;
else
cout<<"Año normal"<<endl;
dias(a);
mostrar_mes(a);
system("pause");
}

void crear_fecha(tfecha &fecha)
{
do{
cout<<"Ingrese dia: ";
cin>>fecha.dia;
cout<<"Ingrese mes: ";
cin>>fecha.mes;
cout<<"Ingrese año: ";
cin>>fecha.anyo;
}while(validar_fecha(fecha)==false);
mostrar_fecha(fecha);
}

bool validar_fecha(tfecha fecha)
{
int dias_mes[12]={31,28,31,30,31,30,31,31,30,31,30,31};
bool valido=true;
if(bisiesto(fecha)==true)
dias_mes[1]=29;
if(fecha.mes<1 || fecha.mes>12 || fecha.dia<1 || fecha.dia>dias_mes[fecha.mes-1])
valido=false;
return valido;
}

void igualdad_fechas(tfecha a, tfecha b)
{
if(a.dia==b.dia && a.mes==b.mes && a.anyo==b.anyo)
cout<<"Son iguales"<<endl;
else
cout<<"Son diferentes"<<endl;
}

void comparar_fechas(tfecha a, tfecha b)
{
if(a.anyo>b.anyo)
cout<<"Es mayor"<<endl;
else{
if(a.anyo<b.anyo)
cout<<"Es menor"<<endl;
else{
if(a.mes>b.mes)
cout<<"Es mayor"<<endl;
else{
if(a.mes<b.mes)
cout<<"Es menor"<<endl;
else{
if(a.dia>b.dia)
cout<<"Es mayor"<<endl;
else
cout<<"Son iguales"<<endl;
}
}
}
}
}

bool bisiesto(tfecha fecha)
{
return (fecha.anyo%4==0 && (fecha.anyo%100!=0 || fecha.anyo%400==0));
}

void dias(tfecha fecha)
{
//Tomar en cuenta que se toma los dias que pasaron desde el 1 de Enero.
//suma_dias[11]={...]; es la suma de dias entre los meses anteriores al mismo.
int cantidad_dias=-1, suma_dias[11]={31,59,90,120,151,181,212,243,273,304,334};//xd
if(fecha.mes<2)
cantidad_dias+=fecha.dia;
else
cantidad_dias+=fecha.dia+suma_dias[fecha.mes-2];
if(fecha.mes>2 && bisiesto(fecha)==true)
cantidad_dias++;
cout<<"Cantidad de dias desde el 1 de Enero: "<<cantidad_dias<<endl;
}

void mostrar_mes(tfecha fecha)
{
switch(fecha.mes){
case 1: cout<<"Enero"<<endl;break;
case 2: cout<<"Febrero"<<endl;break;
case 3: cout<<"Marzo"<<endl;break;
case 4: cout<<"Abril"<<endl;break;
case 5: cout<<"Mayo"<<endl;break;
case 6: cout<<"Junio"<<endl;break;
case 7: cout<<"Julio"<<endl;break;
case 8: cout<<"Agosto"<<endl;break;
case 9: cout<<"Semptiembre"<<endl;break;
case 10: cout<<"Octubre"<<endl;break;
case 11: cout<<"Noviembre"<<endl;break;
case 12: cout<<"Diciembre"<<endl;break;
}
}

void mostrar_fecha(tfecha fecha)
{
cout<<"Fecha: "<<fecha.dia<<"/"<<fecha.mes<<"/"<<fecha.anyo<<endl;
}

7w7