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. (màj : 16 Juin 2019)

17 juin 2019 à 1:13:18

Bonsoir tout le monde, on me demande d'ecrire un programme qui permet à un utilisateur de saisir une date (jour, mois,  année) . Le programme teste si la date est valide. J'ai déclaré le jour,  le mois et l'année mais je ne comprends pas le reste 

  • Partager sur Facebook
  • Partager sur Twitter
Staff 17 juin 2019 à 4:26:14

Bonjour,

Déterrage

Citation des règles générales du forum :

Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.

Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre.
En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.

Au lieu de déterrer un sujet il est préférable :

  • soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
  • soit de créer un nouveau sujet décrivant votre propre contexte
  • ne pas répondre à un déterrage et le signaler à la modération

Je ferme ce sujet. En cas de désaccord, me contacter par MP.

  • Partager sur Facebook
  • Partager sur Twitter