Duda con estructuras en C (Urgente)

Iniciado por jamatbar, 4 Enero 2014, 16:31 PM

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

jamatbar

Buenas, me han pedido un programa en la facultad en el que ,mediante estructuras, me pida dos fechas y el programa me dice si una fecha es posterior/anterior/igual a otra fecha y si los años son bisiestos o no.

Tengo dos ficheros, el primero es fecha.c que hace la lectura, comprobación, comparación, comprobación si es bisiesto o no,  con el código que me ha quedado así:

#include <stdio.h>
#include "fecha.h"

struct fecha leeFecha(void)

{

  struct fecha Fech;

    printf("Introduzca la fecha en formato dd/mm/aaaa: ");

    scanf("%d/%d/%d", &Fech.dia, &Fech.mes, &Fech.año);


  return Fech;
}


int compruebaFecha(struct fecha *pFecha)
{
  int compru;
//  int dia;
// int mes;
  int bis;

  {
    if (pFecha->dia < 1 || pFecha->dia > 31)

      compru = 0;

    else if (pFecha->mes < 1 || pFecha->mes > 12)

      compru = 0;

    else if ((pFecha->mes == 4 || pFecha->mes == 6 || pFecha->mes == 9 || pFecha->mes == 11) && (pFecha->dia > 30))

      compru = 0;

    else if (pFecha->mes == 2)

      {
        if ((bis = 1) && (pFecha->dia > 29))

          compru = 0;

        else if ((bis = 0) && (pFecha->dia > 28))

          compru = 0;
      }

    else

      compru = 1;
  }

  return compru;

}


int comparaFecha(struct fecha f1, struct fecha f2)
/* Función comparaFecha, devuelve:
   -1 si fecha1 < fecha2
   0 si fecha1 = fecha2
   1 si fecha1 > fecha2
*/
{
  int compara;

  if (f1.año < f2.año)
    compara = -1;
  else if (f1.año > f2.año)
    compara = 1;
  else
    {
      if (f1.mes < f2.mes)
        compara = -1;
      else if (f1.mes > f2.mes)
        compara = 1;
      else
        {
          if (f1.dia < f2.dia)
            compara = -1;
          else if (f1.dia > f2.dia)
            compara = 1;
          else
            compara = 0;
        }
    }

  return compara;
}



void imprimeFecha(struct fecha f)
{

  printf("%02d/%02d/%d", f.dia, f.mes, f.año);

  return;
}



// Funcion para comprobar si un año es bisiesto:
int esBisiesto(struct fecha f)
{
  int bis = 0;

  // año bisiesto: {divisible por 4 y no por 100} o {divisible por 400}

  if (((f.año % 4 == 0) && (f.año % 100 != 0)) || (f.año % 400 == 0))
    bis = 1;

  return bis;
}


Aquí está el fichero estructura.c que contiene a la función main y usa las funciones de fecha.c


#include <stdio.h>
#include "fecha.h"

int main()
{
  struct fecha f1;
  struct fecha f2;
  // struct fecha *pf1;
  // struct fecha *pf2;
  int a;
  int compara;
  int bis1;
  int bis2;

  f1 = leeFecha();
  a = compruebaFecha(&f1);

  if (a == 0)
    {
      printf("Formato de fecha incorrecto\n");
    }

  else
    {
      f2 = leeFecha();
      a = compruebaFecha(&f2);

      if (a == 0)
        {
          printf("Formato de fecha incorrecto\n");
        }

      else

        {

          compara = comparaFecha(f1, f2);

/* Imprimir */

          imprimeFecha(f1);
          {
            if (compara > 0)

              printf(" es posterior a ");

            else if (compara == 0)

              printf(" es igual a ");

            else

              printf(" es anterior a ");
          }

          imprimeFecha(f2);

          bis1 = esBisiesto(f1);
          bis2 = esBisiesto(f2);

          {
            if (bis1 == 1 && bis2 == 0)

              printf("\nLa primera fecha es en bisiesto\n");

            else if (bis1 == 0 && bis2 == 1)

              printf("\nLa segunda fecha es en bisiesto\n");

            else if (bis1 == 1 && bis2 == 1)

              printf("\nAmbas fechas son en bisiesto\n");

            else

              printf("\nNinguna de las dos fechas es en bisiesto\n");

          }
        }
    }
  return 0;
}


Y aquí está fecha.h:

#ifndef FECHA_H
#define FECHA_H

struct fecha {
  int dia;
  int mes;
  int año;
};

#define AMBAS_BISIESTO   "Ambas fechas son en bisiesto\n"
#define PRIMERA_BISIESTO "La primera fecha es en bisiesto\n"
#define SEGUNDA_BISIESTO "La segunda fecha es en bisiesto\n"
#define NINGUNA_BISIESTO "Ninguna de las dos fechas es en bisiesto\n"

struct fecha leeFecha( void );
int compruebaFecha( struct fecha *pFecha );
int comparaFecha( struct fecha f1, struct fecha f2 );
void imprimeFecha( struct fecha f );
int esBisiesto( struct fecha f );

#endif



Pues bien, el programa me funciona perfectamente salvo por un pequeño error que no consigo solucionar, puede ser una tontería pero llevo tanto tiempo haciendo el programa que no lo veo.

En la ejecución, si le pongo las fechas 06/01/1981 y 02/06/1980 me dice:

6/1/1981 es posterior a 2/6/1980
La segunda fecha es en bisiesto

¿Cómo consigo que en vez de 6/1/1981 y 2/6/1980 me ponga 06/01/1981 y 02/06/1980?

Es decir, que no se "coma" esos ceros.

¿Alguna ayuda?, gracias de antemano

Necesito que me de la ejecución tal y como digo por que si no no me lo dan como válido el programa, aunque funcione correctamente

Un saludo!

amchacon

Esta línea:
Código (cpp) [Seleccionar]
printf("%d/%d/%d", f.dia, f.mes, f.año);

Cámbiala por:

Código (cpp) [Seleccionar]
printf("%02d/%02d/%04d", f.dia, f.mes, f.año);
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

rir3760

Cita de: jamatbar en  4 Enero 2014, 16:31 PMY aquí está el fichero fecha.h:

#ifndef FECHA_H
#define FECHA_H

struct fecha {
  int dia;
  int mes;
  int año;
};

/* ... */
La solución ya la dio amchacon, otra parte a cambiar en el programa es el nombre del campo "año" ya que en C solo son validos (como parte de un identificador) los caracteres del alfabeto ingles (ello excluye a la 'ñ').

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

jamatbar


dato000

Vaya, es muy buen programa para fechas la verdad, solo una cosa:

es mejor no usar variables con "ñ" puede que de errores de compilación, o bueno, es solo una sugerencia.

año ---> anyo, es muy recomendable no usar ese tipo de caracteres para lenguajes de programación, verás, estos lenguajes son principalmente basados en habla inglesa, donde no existe este caracter.

slds



jamatbar

Respecto a lo de la variable año, yo tengo puesto anyo, pero supongo que por englobar en esta web el código me sale con ñ xD

Me queda una última cosa, que es que cuando le meta las fechas por ejemplo: 29/02/2000 y 29/02/1900 (la primera fecha es correcta ya que el 2000 es un año bisiesto pero el segundo no, ya que el 1900 no es un año bisiesto), entonces tendría que ponerme simplemente el mensaje de "Formato de fecha incorrecto"

Si ahora lo hago me sale el mensaje: 29/02/2000 es posterior a 29/02/1900 La primera fecha es en bisiesto

¿Alguna ayuda?

Saludos!

dato000

Pues solo seria mostrar el mensaje en pantalla no?? ya comprobaste todo dentro de las funciones

Ya hiciste todo el trabajo sucio, solo es indicarlo en pantalla para el usuario.


bis1 = esBisiesto(f1);
bis2 = esBisiesto(f2);
{
     if (bis1 == 1 && bis2 == 0)
     {
              printf("\nLa primera fecha es en bisiesto");
              printf("\nLa segunda fecha no es bisiesto\n");
     }
     
     else if (bis1 == 0 && bis2 == 1)
     {
              printf("\nLa primera fecha no es bisiesto");
              printf("\nLa segunda fecha es en bisiesto\n");
     }
           
     else if (bis1 == 1 && bis2 == 1)
              printf("\nAmbas fechas son en bisiesto\n");

     else
              printf("\nNinguna de las dos fechas es en bisiesto\n");

}



jamatbar

Cita de: dato000 en  4 Enero 2014, 21:18 PM
Pues solo seria mostrar el mensaje en pantalla no?? ya comprobaste todo dentro de las funciones

Ya hiciste todo el trabajo sucio, solo es indicarlo en pantalla para el usuario.


bis1 = esBisiesto(f1);
bis2 = esBisiesto(f2);
{
    if (bis1 == 1 && bis2 == 0)
    {
             printf("\nLa primera fecha es en bisiesto");
             printf("\nLa segunda fecha no es bisiesto\n");
    }
   
    else if (bis1 == 0 && bis2 == 1)
    {
             printf("\nLa primera fecha no es bisiesto");
             printf("\nLa segunda fecha es en bisiesto\n");
    }
           
    else if (bis1 == 1 && bis2 == 1)
             printf("\nAmbas fechas son en bisiesto\n");

    else
             printf("\nNinguna de las dos fechas es en bisiesto\n");

}


No pero no es eso lo que busco, lo que busco es que si por ejemplo pongo las fechas que he dicho (29/02/2000 y 29/02/1900) al ser la segunda una fecha incorrecta ,ya que no existe, que ponga sólo por pantalla "Formato de fecha incorrecto".

Poner que no es bisiesto estaría mal ya que el 29/02/1900 directamente es una fecha que no existe puesto que al no ser bisiesto el 29 de Febrero no existe xD

dato000

pues entonces el control tendria que ser mucho más estricto, especificandole al usuario que debe saber exactamente cuales son la cantidad de dias hay en cada mes en particular, incluyendo el mes bisiesto, dentro de las condiciones de los meses y dias, tendria que hacerse un ciclo (yo usaria un while).

En el que solo pueda usarse digamos, en enero, que solo tiene 31 días, no recibir la fecha que se use en el mes de enero --> DD/01/AAAA si es menor a 1 y mayor a 31, puesto que es incorrecto, indicandole al usuario que digite un fecha correcta, y así, se valide correctamente la información, en primera debe hacerse un control así en cada mes, dependiendo de la cantidad de días, y luego sería hacer un control particular sobre febrero, aunque lo indicado sería orientar al usuario sobre cuales años son biciestos. 



jamatbar

Gracias por la ayuda aunque no tengo ni idea de como hacerlo :S