Partage
  • Partager sur Facebook
  • Partager sur Twitter

Fonction qui calcul la validité d'une date

    27 décembre 2006 à 23:07:01

    Bonjour, j'ai écris le code d'un petit programme qui est censé calculer le lendemain d'une date préalablement rentrée au clavier, mais voilà lors de l'exécution du programme tout se passe bien sauf que si je rentre une fin d'année (exemple: 31/12/2006) la fonction me renvoie 1/13/2006.

    J'ai relus plusieurs fois mon code et je ne vois toujours pas ce qui cloche:

    #include <stdio.h>
    #include <stdlib.h>

    // retourne 1 si l'anne est bissextile et 0 si c'est le contraire
    int bissextile(int an)
    {
       if (an%400==0) return 1;
       if (an%100==0) return 0;
       if (an%4==0) return 1;
       return 0;
    }

    // retourne la longueur du mois selon le mois et l'année
    int longueur_mois(int m,int a)
    {
        switch(m)
        {
        case 1: return 31;
        case 2:
             if (bissextile(a))
             return 29;
             else
             return 28;
        case 3: return 31;
        case 4: return 30;
        case 5: return 31;
        case 6: return 30;
        case 7: return 31;
        case 8: return 31;
        case 9: return 30;
        case 10: return 31;
        case 11: return 30;
        case 12: return 31;
        default: return 0;
        }
    }

    // retourne 0 si la date n'est pas valide et 1 dans le cas contraire
    int est_valide(int j, int m, int a)
    {
        if (((j > 0) && (j <= longueur_mois(m,a)) && ((m > 0) && (m < 13))))
        return 1;
        else
        return 0;
    }

    // renvoi vrai si la date est une fin de mois
    int fin_mois(int j, int m, int a)
    {
        if (j == longueur_mois(m,a))
        return 1;
    }

    // renvoi vrai si la date est une fin d'année
    int fin_annee(int j, int m, int a)
    {
        if ((m == 12) && (j == fin_mois(j,m,a)))
        return 1;
    }

    void lendemain(int j,int m,int a)
    {
        int j2=j;
        int m2=m;
        int a2=a;

        if (est_valide(j2+1,m2,a2))
        j2++;
        else
        {
            j2=1;
            if (fin_annee(j2,m2,a2))
            {
                m2=1;
                a2++;
            }
            else
            m2++;
        }

        printf("La date du lendemain est: %d/%d/%d \n",j2,m2,a2);
    }

    int main(int argc, char *argv[])
    {
        int j,m,a;
        printf("Entrer le jour: ");
        scanf("%d",&j);
        printf("Entrer le mois: ");
        scanf("%d",&m);
        printf("Entrer l'annee: ");
        scanf("%d",&a);
        lendemain (j,m,a);

      system("PAUSE");
      return 0;
    }


    Ps: je sais j'aurais pu utiliser les pointeurs pour la fonction mais là n'est pas la question, merci d'avance de votre aide.
    • Partager sur Facebook
    • Partager sur Twitter
      28 décembre 2006 à 0:10:36

      essaie un "if 'mois > 12 then mois = 1"...
      • Partager sur Facebook
      • Partager sur Twitter
        28 décembre 2006 à 0:18:17

        salut....
        à mon avis le problem vient de ta fonction fin_annee

        ton code:
        // renvoi vrai si la date est une fin d'année
        int fin_annee(int j, int m, int a)
        {
            if ((m == 12) && (j == fin_mois(j,m,a)))
            return 1;
        }

        alors que tu sais que le dernier mois de l'année c'est decembre et donc un mois de 31 jour :p come ca ta meme pas besoin de l'année en paramètre.
        // renvoi vrai si la date est une fin d'année
        int fin_annee(int j, int m)
        {
            if ((m == 12) && (j ==31))
            return 1;
        }



        EDIT:

        sinn tu met ca et ta mêm pas besoin d'appeler la fonction fin_annee ;)
        void lendemain(int j,int m,int a)
        {
            int j2=j;
            int m2=m;
            int a2=a;

            if (est_valide(j2+1,m2,a2))
            j2++;
            else
            {
                if (m2==12 && j2==31)
                  {
                        m2=1
                        j2=1
                        a2+=1

                  }
                else
                  {
                        m2++
                        j2++
                  }
            }
        }


        PS: je susi débutant.
        • Partager sur Facebook
        • Partager sur Twitter
          28 décembre 2006 à 0:43:36

          Voila, j'ai reussi a le corrige (enfin je croit :p ) :

          #include <stdio.h>
          #include <stdlib.h>

          int bissextile(int an);
          int longueur_mois (int m, int a);
          void lendemain (int j, int m, int a);

          int main (int argc, char *argv[])
          {
              int j,m,a;

              printf ("Entrer le jour: ");
              scanf ("%d",&j);

              printf ("Entrer le mois: ");
              scanf ("%d",&m);

              printf("Entrer l'annee: ");
              scanf ("%d",&a);

              lendemain (j, m, a);

              return 0;
          }

          // retourne 1 si l'anne est bissextile et 0 si c'est le contraire
          int bissextile (int a)
          {
             if (a % 400 == 0)
                  return 1;

             if (a % 100 ==0)
                  return 0;

             if (a % 4 == 0)
                  return 1;

             return 0;
          }

          // retourne la longueur du mois selon le mois et l'année
          int longueur_mois (int m, int a)
          {
              switch(m)
              {
              case 1: return 31;
              case 2:
                   if (bissextile(a))
                   return 29;
                   else
                   return 28;
              case 3: return 31;
              case 4: return 30;
              case 5: return 31;
              case 6: return 30;
              case 7: return 31;
              case 8: return 31;
              case 9: return 30;
              case 10: return 31;
              case 11: return 30;
              case 12: return 31;
              default: return 0;
              }
          }

          void lendemain (int j, int m, int a)
          {
              if (j > 0 && j < longueur_mois (m, a) && m > 0 && m <= 12)
                  j++;

              else
              {
                  j = 1;

                  if (m == 12)
                  {
                      m = 1;
                      a++;
                  }

                  else
                      m++;
              }

              printf ("La date du lendemain est: %d/%d/%d \n", j, m, a);
          }



          En gors le probleme venait de ton test de validite, de ton incrementation d'annee et de mois, et de tes declaration de variable, j'ai oter queqlue fonction et quelques variable complketement inutile.
          • Partager sur Facebook
          • Partager sur Twitter
          FaQ : Fr | En 1 2 | C++11 | Template || Blog : Deloget | C++|Boost--Dev | C++Next | GotW || Installer Boost
            28 décembre 2006 à 1:34:45

            Citation : 62JoulS

            Bonjour, j'ai écris le code d'un petit programme qui est censé calculer le lendemain d'une date préalablement rentrée au clavier, mais voilà lors de l'exécution du programme tout se passe bien sauf que si je rentre une fin d'année (exemple: 31/12/2006) la fonction me renvoie 1/13/2006.


            Les effets ravageurs d'un usage abusif de return et d'une mauvaise indentation. On fini par écrire des fonctions qui non pas de return dans certains cas.

            // renvoi vrai si la date est une fin de mois
            int fin_mois (int j, int m, int a)
            {
               if (j == longueur_mois (m, a))
                  return 1;
            }

            // renvoi vrai si la date est une fin d'année
            int fin_annee (int j, int m, int a)
            {
               if ((m == 12) && (j == fin_mois (j, m, a)))
                  return 1;
            }

            Heureusement, un bon compilateur bien reglé s'en aperçoit...


            Project : Forums
            Compiler : GNU GCC Compiler (called directly)
            Directory : C:\dev\forums2\
            --------------------------------------------------------------------------------
            Switching to target: default
            Compiling: main.c
            main.c: In function `fin_mois':
            main.c:67: warning: control reaches end of non-void function
            main.c: In function `fin_annee':
            main.c:74: warning: control reaches end of non-void function
            Linking console executable: C:\dev\forums2\console.exe
            Process terminated with status 0 (0 minutes, 4 seconds)
            0 errors, 2 warnings

            Je prône le return unique pour chaque fonction...
            • Partager sur Facebook
            • Partager sur Twitter
            Music only !
              28 décembre 2006 à 16:45:37

              Eh bien mes fonctions fin_mois et fin_annee ne comportent qu'un return chacunes, je ne comprends pas ce qui cloche ?
              • Partager sur Facebook
              • Partager sur Twitter
                28 décembre 2006 à 16:50:43

                Citation : 62JoulS

                Eh bien mes fonctions fin_mois et fin_annee ne comportent qu'un return chacunes, je ne comprends pas ce qui cloche ?


                Il y a des cas où il n'y a pas de return du tout, donc la valeur retournée est indéfinie. Ca invoque un comportement indéfini, ce qui est un bug gravissime.

                Quand je dis "un return par fonction", ça veut dire que return est la dernière instruction :

                int f(des_parametres)
                {
                   int xxx = 0;

                   /* tout ce qu'on veut sauf return */

                   return xxx;
                }

                Ecrit toutes tes fonctions sur ce modèle et tu n'auras plus jamais ce problème.
                • Partager sur Facebook
                • Partager sur Twitter
                Music only !
                  28 décembre 2006 à 17:39:15

                  J'ai modifié mon code ainsi mais rien y fait, en principe ça devrait marcher:
                  #include <stdio.h>
                  #include <stdlib.h>

                  // retourne vrai si l'année entrée est bissextile et faux pour le contraire
                  int bissextile(int an)
                  {
                     if (an%400==0) return 1;
                     if (an%100==0) return 0;
                     if (an%4==0) return 1;
                     return 0;
                  }

                  // retourne la longueur du mois en fonction du mois et de l'année
                  int longueur_mois(int m,int a)
                  {
                      switch(m)
                      {
                          case 1: return 31;
                          case 2:
                          if (bissextile(a))
                          return 29;
                          else
                          return 28;
                          case 3: return 31;
                          case 4: return 30;
                          case 5: return 31;
                          case 6: return 30;
                          case 7: return 31;
                          case 8: return 31;
                          case 9: return 30;
                          case 10: return 31;
                          case 11: return 30;
                          case 12: return 31;
                          default: return 0;
                      }
                  }

                  // renvoi vrai si la date est une fin d'année
                  int fin_annee(int j, int m, int a)
                  {
                      int vof;
                      if (j==longueur_mois(m,a) && m==12)
                          vof=1;
                      else
                          vof=0;
                      return vof;
                  }

                  // renvoi vrai si la date est une fin de mois
                  int fin_mois(int j,int m,int a)
                  {
                      int vof;
                      if (j=longueur_mois(m,a))
                          vof=1;
                      else
                          vof=0;
                      return vof;
                  }

                  int est_valide(int j, int m, int a)
                  {
                      int vof;
                      if ((j>0 && j<=longueur_mois(m,a)) && (m>0 && m<13))
                          vof=1;
                      else
                          vof=0;
                      return vof;
                  }

                  void lendemain(int j, int m, int a)
                  {
                      int j2,m2,a2;
                      if (est_valide(j,m,a))
                          {
                              if (fin_annee(j,m,a))
                                  {j2=1;m2=1;a2=a+1;}
                              else if (fin_mois(j,m,a))
                                  {j2=1;m2=m+1;a2=a;}
                              else
                                  {j2=j+1;m2=m;a2=a;}

                              printf("%d/%d/%d",j2,m2,a2);
                          }
                      else
                          printf("Cette date n'est pas valide !");
                  }

                  // fonction de test
                  void essai()
                  {
                      int j,m,a;
                      printf("Donner le jour: ");
                      scanf("%d",&j);
                      printf("Donner le mois: ");
                      scanf("%d",&m);
                      printf("Donner l'annee: ");
                      scanf("%d",&a);
                      lendemain(j,m,a);
                  }


                  int main(int argc, char *argv[])
                  {
                      essai();

                    return 0;
                  }


                  ps: merci pour ceux qui m'ont proposé d'autres solutions mais je veux integrer toutes les fonctions présentes car j'en aurai besoin par la suite.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    28 décembre 2006 à 18:49:58

                    Essay de reprendre mon code, tu recrer les 2 fonctions que j'ai oter et les variables que j'ai oter aussi, je les avait oter car avec ce que tu nous avez dit elles etaient inutiles.
                    • Partager sur Facebook
                    • Partager sur Twitter
                    FaQ : Fr | En 1 2 | C++11 | Template || Blog : Deloget | C++|Boost--Dev | C++Next | GotW || Installer Boost
                      25 avril 2019 à 18:43:12

                      salut;

                      quand jai tester votre code j'ai trouver un grand probleme

                      si l'utilisateur choisir 33 comme nombre de jour .. votre programme calcule la date normalement

                      il faut que vous ajouter une autre fonction qui teste la validéte des valeurs entree par l'utilisateur!!!

                      • Partager sur Facebook
                      • Partager sur Twitter
                        29 avril 2019 à 12:00:53

                        Salut,

                        C'est à titre d'exercice ou bien seule la finalité compte ? Parce que dans le second cas, il suffit de passer par la lib time.h.

                        On renseigne une struct tm, on la passe en time_t à laquelle on ajoutes 86400 (secondes par jour) et on la repasse en struct tm pour relever la date.

                        Bonne continuation.

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Stringman | Jeux de plateforme : Nouvelle Démo.

                        Fonction qui calcul la validité d'une date

                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                        • Editeur
                        • Markdown