OVH Cloud OVH Cloud

Meilleure façon de demander la date ?

39 réponses
Avatar
Eddahbi Karim
Bonjour, Bonsoir,

Voilà je continue les exercices de mon bouquin de C.
J'en suis au chapitre concernant les structures et ils demandent de créer
une structure contenant le temps et la date. (Puis de calculer l'espace
entre deux temps en minutes).

Ma question est :

Est-il mieux de demander à l'utilisateur de rentrer la date comme ceci :
- mm/jj/aaaa
Puis de prendre les valeurs mm et jj, avec un srtoi (C99) ou un strtod
(Ansi) quit à caster en int après, et de les vérifier. Ou
- mm jj aaaa
Puis de prendre après les valeurs à l'aide d'un sscanf(input,"%d %d %d",
...) pour les vérifier après.

Et pour le temps vous avez une idée ?
J'ai pensé que la méthode 88:88 serait pas mal mais si vous avez une autre
idée ;).

Merci,
Voila ;),
ThE_TemPLaR

10 réponses

1 2 3 4
Avatar
AG
Emmanuel Delahaye wrote:
In 'fr.comp.lang.c', AG wrote:


Voilà je continue les exercices de mon bouquin de C.
J'en suis au chapitre concernant les structures et ils demandent de créer
une structure contenant le temps et la date. (Puis de calculer l'espace
entre deux temps en minutes).


J'aurais naturellement utilisé time() qui donne le temps, plutot que de
parser une chaine. (mais c'est un autre exercice).



Rien à voir avec la question posée...


Si



Avatar
Claudio
Bonjour, Bonsoir,

Voilà je continue les exercices de mon bouquin de C.
J'en suis au chapitre concernant les structures et ils demandent de créer
une structure contenant le temps et la date. (Puis de calculer l'espace
entre deux temps en minutes).

Ma question est :

Est-il mieux de demander à l'utilisateur de rentrer la date comme ceci :
- mm/jj/aaaa
Puis de prendre les valeurs mm et jj, avec un srtoi (C99) ou un strtod
(Ansi) quit à caster en int après, et de les vérifier. Ou
- mm jj aaaa
Puis de prendre après les valeurs à l'aide d'un sscanf(input,"%d %d %d",
...) pour les vérifier après.

Et pour le temps vous avez une idée ?
J'ai pensé que la méthode 88:88 serait pas mal mais si vous avez une autre
idée ;).

Merci,
Voila ;),
ThE_TemPLaR

Salut,


"diviser pour régner", telle devrait etre la devise de tout bon
programmeur ! Il faut découper un problème, en plusieurs sous-pbs plus
petits, autonomes, qui seront plus faciles à résoudre.
C'est la base de la programmation "modulaire" , et le C n'y échappe pas.

A mon avis, tu as intéret à diviser le pb comme suit:
- saisie d'un chaine quelconque , avec une taille limitée, mais
confortable (genre 20). => fgets()
- définition d'un format. Tu utiliseras un format particulier (ex:
jj/mm/aaaa) dans ton prog, sous forme de structure, sachant que tu
pourras le faire évoluer facilement (définition d'une autre structure
aammjj). Ca pourra faire l'objet d'un autre exercice !
- A chaque structure , correspond un "parsing", c'est à dire une règle
de correspondance 'position-longueur' dans la chaine saisie <=> donnée à
controler. => sscanf()
- La donnée à controler sera sous forme numérique.

Ce qui implique que dans ta structure, les champs aaaa mm jj sont
numériques (ex:unsigned int). De plus , tu dois voir qu'il y a deux
niveaux de controle bien distincts:
1er niveau: controle que ce qui est saisi est numérique (mauvais ex:
10/05/$003) et positif.
2ème niveau, après "parsing": controle du mois (entre 01 et 12) etc...

Une fois que ces 2 niveaux sont franchis , alors tu peux exploiter tes
structures pour faire des calculs de temps.

Avatar
Eddahbi Karim
Merci beaucoup pour toutes vos réponses, j'ai opté pour la solution :

fgets(input, (int) sizeof(input), stdin);
if ( sscanf(input,"%d/%d/%d", &month, &day, &year != 3 )
{
...
}

Car elle me parait la plus simple, la plus rapide et la plus efficace.
Le problème est que si la personne entre 0005, je n'ai aucun moyen de le
savoir et de l'arrêter, ce qui fait que la date peut dépasser la longueur
autorisée : mm.

Sinon le problème qui se pose c'est pour vérifier la date.

Y'a bien la méthode :

if ( ( month == 6 ) && ( ( day < 1 ) || ( day > 30 ) )
{
...
err = EXIT_FAILURE;
}
else if...

switch(month)
{
...

case 6 : if ( ( day < 1 ) || ( day > 30 )
...
break;

...
}


Mais ça semble assez long, si quelqu'un à une autre idée.

Merci beaucoup,
Voila ;),
ThE_TemPLaR
Avatar
Eddahbi Karim

if ( sscanf(input,"%d/%d/%d", &month, &day, &year != 3 )
if ( sscanf(input,"%d/%d/%d", &month, &day, &year) != 3 )


On a rien vu :D.

ThE_TemPLaR

Avatar
AG
Eddahbi Karim wrote:


if ( sscanf(input,"%d/%d/%d", &month, &day, &year != 3 )


if ( sscanf(input,"%d/%d/%d", &month, &day, &year) != 3 )


Dans ce cas pourquoi ne pas utiliser directement fscanf() ?


Avatar
Antoine Leca
if ( sscanf(input,"%d/%d/%d", &month, &day, &year) != 3 )


Dans ce cas pourquoi ne pas utiliser directement fscanf() ?


Parce que s'il y a une erreur de correspondance, tu laisses
le flux d'entrée dans un état connu si tu as tout lu avec
fgets(), tandis qu'avec fscanf() tu t'es arrêté au milieu,
mais tu ne sais pas où. Et impossible de continuer proprement.

Oublie fscanf() pour des entrées utilisateur, ce n'est pas
fait pour cela (et je n'ai aucune idée de pourquoi scanf()
peut bien exister).


Antoine


Avatar
Bertrand Mollinier Toublet
Eddahbi Karim wrote:
Merci beaucoup pour toutes vos réponses, j'ai opté pour la solution :

fgets(input, (int) sizeof(input), stdin);
if ( sscanf(input,"%d/%d/%d", &month, &day, &year != 3 )
{
....
}

Car elle me parait la plus simple, la plus rapide et la plus efficace.
Le problème est que si la personne entre 0005, je n'ai aucun moyen de le
savoir et de l'arrêter, ce qui fait que la date peut dépasser la longueur
autorisée : mm.

Sinon le problème qui se pose c'est pour vérifier la date.

Y'a bien la méthode :

if ( ( month == 6 ) && ( ( day < 1 ) || ( day > 30 ) )
{
....
err = EXIT_FAILURE;
}
else if...

switch(month)
{
....

case 6 : if ( ( day < 1 ) || ( day > 30 )
...
break;

....
}


Mais ça semble assez long, si quelqu'un à une autre idée.

Moi, ca me parait bien. Y'a pas tant de mois differents. En admettant:


int day, month, year;

enum
{
JAN = 1,
FEV,
MAR,
AVR,
MAI,
JUN,
JUI,
AOU,
SEP,
OCT,
NOV,
DEC
};

switch (month)
{
case JAN:
case MAR:
case MAI:
case JUI:
case AOU:
case OCT:
case DEC:
if ((0 < day) || (day <= 31))
{
/* err: mauvais jour */
}
break;
case FEV:
if ((0 < day) || (day <= 28))
{
/* err: mauvais jour */
}
break;
case AVR:
case JUN:
case SEP:
case NOV:
if ((0 < day) || (day <= 30))
{
/* err: mauvais jour */
}
break;
default:
/*err: mauvais mois */
break;
}

non ?
--
Bertrand Mollinier Toublet
"Reality exists" - Richard Heathfield, 1 July 2003

Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Eddahbi Karim
wrote:

fgets(input, (int) sizeof(input), stdin);


Il faut s'assurer que l'entrée n'a pas été tronquée, et qu'il ne reste pas
des caractères dans stdin. En cas de troncature, pas la peine d'aller plus
loin, et rappel au reglement!

if ( sscanf(input,"%d/%d/%d", &month, &day, &year != 3 )
{
...
}

Car elle me parait la plus simple, la plus rapide et la plus efficace.
Le problème est que si la personne entre 0005, je n'ai aucun moyen de le
savoir et de l'arrêter, ce qui fait que la date peut dépasser la longueur
autorisée : mm.


Voir au dessus!

Sinon le problème qui se pose c'est pour vérifier la date.

Y'a bien la méthode :

if ( ( month == 6 ) && ( ( day < 1 ) || ( day > 30 ) )
{
...
err = EXIT_FAILURE;
}
else if...

switch(month)
{
...

case 6 : if ( ( day < 1 ) || ( day > 30 )
...
break;

...
}


Un tableau de 12 entiers non signés avec le nombre de jours.

J'ai une bidouille comme ça dans ma bibliothèque perso (brut de décoffrage,
désolé, mais là, ce n'est plus de la théorie, c'est du vrai! ):

#ifndef H_AETA_DATE_20030327171623
#define H_AETA_DATE_20030327171623

#ifdef __cplusplus
extern "C"
{
#endif

/* ---------------------------------------------------------------------
(c) AETA 2000
Projet : CLIB
Fonction : Gestion des dates
Module : DATE
Fichier : DATE.H
Creation : 10-01-2000
Modification : 06-05-2003
--------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
Journal

0.0 du 10-01-2000 Creation
1.0 du 11-01-2000 Version operationelle
1.1 du 26-03-2003 Ajout de la structure sDATE et des fonctions de
. conversion 'struct tm' <-> 'sDATE'
2.0 du 23-04-2003 Les anciennes fonctions 'tm' deviennent DATE_tm_*()
. Les fonctions DATE_*() utilisent sDATE
2.1 du 28-04-2003 Dans DATE2tm(), ajout de 'tm_isdst = 0'
2.2 du 29-04-2003 Ajout des formats standard pour printf DATE_FTM_xxx
2.3 du 06-05-2003 Ajout de DATE_print() (si DATE_PRINT est defini)

---------------------------------------------------------------------

* ATTENTION *

Les anciennes fonctions

int DATE_limites (struct tm const *const p_tm);
int DATE_valide (struct tm const *const p_tm);
int DATE_jour_max (struct tm const *const p_tm);

utilisent la structure standard 'tm' sans en respecter les
specifications (notament concernant tm_year et tm_mon).

Elles ont ete renommees. Elles s'appellent maintenant :

int DATE_tm_limites (struct tm const *const p_tm);
int DATE_tm_valide (struct tm const *const p_tm);
int DATE_tm_jour_max (struct tm const *const p_tm);

L'usage des anciennes fonctions DATE_tm*() est desormais interdit dans
de nouveaux projets. Dans les anciens, il faut si possible les remplacer
par les nouvelles fonctions correspondantes.

int DATE_is_valid (sDATE const *const p_date);
int DATE_last_day (sDATE *date);

La fonction DATE_is_valid() remplace les fonctions DATE_tm_limites()
et DATE_tm_valide()

L'activation des anciennes fonctions se fait en definissant la macro
globale :

DATE_TM

REMARQUE

Pour le moment, les fonctions

int DATE_Date2tm (char const *s_date, struct tm *const p_tm);
int DATE_Time2tm (char const *s_time, struct tm *const p_tm);

utilisant des fonctions internes de DATE_tm(), elle ne sont accessibles
que si DATE_TM est defini.

--------------------------------------------------------------------- */
#include <time.h>

/* macros ============================================================== */
/* constants =========================================================== */

#define DATETIME2tm 1 /* 0 | 1 */

/* format d'affichage standard */
#define DATE_FMT_DATE "%04d-%02u-%02u"
#define DATE_FMT_TIME "%02u:%02u:%02u"
#define DATE_FMT_FULL DATE_FMT_DATE " " DATE_FMT_TIME


/* types =============================================================== */
/* structures ========================================================== */

typedef struct
{
/* 16 bits */
int year; /* -32767..+32767 */
unsigned month:4; /* 0-15 */
unsigned day:5; /* 0-31 */

unsigned hour:5; /* 0-31 */
unsigned minute:6; /* 0-63 */
unsigned second:6; /* 0-63 */
}
sDATE;

/* internal public data ================================================ */
/* internal public functions =========================================== */
/* entry points ======================================================== */

/* ---------------------------------------------------------------------
DATE_sver()
---------------------------------------------------------------------
Role : Retourne une chaine "Version"
---------------------------------------------------------------------
E :
S : Pointeur de chaine ASCIIZ
--------------------------------------------------------------------- */
const char *DATE_sver (void);

/* ---------------------------------------------------------------------
DATE_sid()
---------------------------------------------------------------------
Role : Retourne une chaine "Identification"
---------------------------------------------------------------------
E :
S : Pointeur de chaine ASCIIZ
--------------------------------------------------------------------- */
const char *DATE_sid (void);

/* ---------------------------------------------------------------------
DATE_annee4()
---------------------------------------------------------------------
Role : Conversion d'une date modulo 100 en date 4 digit
---------------------------------------------------------------------
E : date charniere
E : date sur 2 chiffres (0-99)
S : date sur 4 chiffres (charniere - charniere+99)
--------------------------------------------------------------------- */
int DATE_annee4 (int const yy, int const y2);

/* ---------------------------------------------------------------------
DATE_is_valid()
---------------------------------------------------------------------
Role : tester la validite d'une date
---------------------------------------------------------------------
E : structure date (sDATE)
S : 1=ok 0=err
--------------------------------------------------------------------- */
int DATE_is_valid (sDATE const *const p_date);

/* ---------------------------------------------------------------------
DATE_jour_max()
---------------------------------------------------------------------
Role : Retourne le jour max en fonction de la date courante
---------------------------------------------------------------------
E : structure date (sDATE)
S :
--------------------------------------------------------------------- */
int DATE_jour_max (sDATE *date);

/* ---------------------------------------------------------------------
tm2DATE()
---------------------------------------------------------------------
Role : Conversion d'une date standard C en sDATE
---------------------------------------------------------------------
E : adresse de sortie (sDATE)
E : adresse de la date d'entree (struct tm)
S : 0=ok 1=err
--------------------------------------------------------------------- */
int tm2DATE (sDATE *const p_date, struct tm const *const p_tm);

/* ---------------------------------------------------------------------
DATE2tm()
---------------------------------------------------------------------
Role : Conversion d'une date sDATE en standard C
---------------------------------------------------------------------
E : adresse de sortie (struct tm)
E : adresse de la date d'entree (sDATE)
S : 0=ok 1=err
--------------------------------------------------------------------- */
int DATE2tm (struct tm *const p_tm, sDATE const *const p_date);

#ifdef DATE_PRINT
/* ----------------------------------------------------------------------
DATE_print()
----------------------------------------------------------------------

----------------------------------------------------------------------
E: structure interne de date
S:
---------------------------------------------------------------------- */
void DATE_print (sDATE const *const p_date);
#endif



#ifdef DATE_TM
/* ---------------------------------------------------------------------
DATE_tm_limites()
---------------------------------------------------------------------
Role : tester le limites d'une date
---------------------------------------------------------------------
E : structure standard date (tm)
S : 0=OK -1=KO
--------------------------------------------------------------------- */
int DATE_tm_limites (struct tm const *const p_tm);

/* ---------------------------------------------------------------------
DATE_tm_valide()
---------------------------------------------------------------------
Role : tester la validite d'une date
---------------------------------------------------------------------
E : structure standard date (tm)
S : 0=OK -1=KO
--------------------------------------------------------------------- */
int DATE_tm_valide (struct tm const *const p_tm);

/* ---------------------------------------------------------------------
DATE_tm_jour_max()
---------------------------------------------------------------------
Role : Retourne le jour max en fonction de la date courante
---------------------------------------------------------------------
E : structure standard date (tm)
S :
--------------------------------------------------------------------- */
int DATE_tm_jour_max (struct tm const *const p_tm);

#if DATETIME2tm
/* ---------------------------------------------------------------------
DATE_Date2tm()
---------------------------------------------------------------------
Role : Convertir une date au format __DATE__ au format tm
(les autres champs ne sont pas modifies)
---------------------------------------------------------------------
E : chaine sur __DATE__
E : structure standard date (tm)
S : 0=OK -1=KO
--------------------------------------------------------------------- */
int DATE_Date2tm (char const *s_date, struct tm *const p_tm);

/* ---------------------------------------------------------------------
DATE_Time2tm()
---------------------------------------------------------------------
Role : Convertir une heure au format __TIME__ au format tm
(les autres champs ne sont pas modifies)
---------------------------------------------------------------------
E : chaine sur __TIME__
E : structure standard date (tm)
S : 0=OK -1=KO
--------------------------------------------------------------------- */
int DATE_Time2tm (char const *s_time, struct tm *const p_tm);
#endif /* DATETIME2tm */

#endif /* DATE_TM */

/* public data ========================================================= */

/* File generated by 'NEW.EXE' Ver 1.20 (c) ED 1998-99 */

#ifdef __cplusplus
}
#endif

#endif /* H_AETA_DATE_20030327171623 */

/* Guards added by GUARD (c) AETA 2000-2003 Feb 14 2003 Ver. 1.5 */



/* ---------------------------------------------------------------------
(c) AETA 2000-2003
Projet : CLIB
Fonction : Gestion des dates
Module : DATE
Fichier : DATE.C
Creation : 10-01-2000
Modification : 06-05-2003
--------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
Journal

0.0 du 10-01-2000 Creation
1.0 du 11-01-2000 Version operationelle
1.1 du 26-03-2003 Ajout de la structure sDATE et des fonctions de
. conversion 'struct tm' <-> 'sDATE'
2.0 du 23-04-2003 Les anciennes fonctions 'tm' deviennent DATE_tm_*()
. Les fonctions DATE_*() utilisent sDATE
2.1 du 28-04-2003 Dans DATE2tm(), ajout de 'tm_isdst = 0'
2.2 du 29-04-2003 Ajout des formats standard pour printf DATE_FTM_xxx
2.3 du 06-05-2003 Ajout de DATE_print() (si DATE_PRINT est defini)
--------------------------------------------------------------------- */
#ifdef __cplusplus
#error This source file is not C++ but rather C. Please use a C-compiler
#endif

#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "ed/inc/date.h"
#include "ed/inc/str.h"
#include "ed/inc/sys.h"
#include "ed/inc/sysalloc.h"

#ifdef DATE_PRINT
#include <stdio.h>
#endif

/* macros ============================================================== */

#define MODULE "DATE"
#define VER "2.3"
#define ID "DATE Module "C" (c) AETA 2000-2003"

/* constants =========================================================== */

#ifdef DATE_TM

#if DATETIME2tm

#define SEP_D " "
#define SEP_H ":"

/* juste pour avoir la taille */
static char const szDATE[] = __DATE__;
static char const szTIME[] = __TIME__;

#endif /* DATETIME2tm */

#endif /* DATE_TM */

/* MONth TO Number Of Days */
static int const Mon2nod[] {
0
,31 /* Jan */
,28 /* Feb */
,31 /* Mar */
,30 /* Apr */
,31 /* May */
,30 /* Jun */
,31 /* Jul */
,31 /* Aug */
,30 /* Sep */
,31 /* Oct */
,30 /* Nov */
,31 /* Dec */
};

/* types =============================================================== */
/* structures ========================================================== */
/* private data ======================================================== */
/* private functions =================================================== */

/* ---------------------------------------------------------------------
is_leap()
---------------------------------------------------------------------
Role :
---------------------------------------------------------------------
E : year (YYYY)
S : 0=err 1=ok
--------------------------------------------------------------------- */
int is_leap (unsigned const year)
{
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}

#ifdef DATE_TM
/* ---------------------------------------------------------------------
tm_is_valid()
---------------------------------------------------------------------
OBSOLETE
---------------------------------------------------------------------
E :
S : 0=OK -1=KO
--------------------------------------------------------------------- */
static int tm_is_valid (struct tm const *const p_tm, int *const day_max)
{
int cr = -1;
int month = p_tm->tm_mon;

if (month <= 12
&& month >= 1)
{
int nod = Mon2nod[month];
int year = p_tm->tm_year;

if (p_tm->tm_mon == 2) /* Fevrier */
{

if (is_leap (year))
{
nod = 29;
}
}

if (p_tm->tm_mday > 0
&& p_tm->tm_mday <= nod)
{
if (day_max)
{
*day_max = nod;
}

cr = 0;
}
}
return cr;
}
#endif /* DATE_TM */

/* ---------------------------------------------------------------------
is_valid()
---------------------------------------------------------------------
Role :
---------------------------------------------------------------------
E :
S : 1=OK 0=KO
--------------------------------------------------------------------- */
static int is_valid (sDATE const *const p_date, int *const p_last_day)
{
int ok = 0;
unsigned month = p_date->month;

if (month <= 12
&& month >= 1)
{
unsigned nod = Mon2nod[month];
unsigned year = p_date->year;

if (month == 2) /* Fevrier */
{
if (is_leap (year))
{
nod = 29;
}
}

if (p_date->day > 0
&& p_date->day <= nod)
{
if (p_last_day)
{
*p_last_day = nod;
}

if (p_date->hour < 24)
{
if (p_date->minute < 60)
{
if (p_date->second < 60)
{
ok = 1;
}
}
}
}
}
return ok;
}

/* internal public data ================================================ */
/* internal public functions =========================================== */
/* entry points ======================================================== */

/* ---------------------------------------------------------------------
DATE_sver()
---------------------------------------------------------------------
Role : Retourne une chaine "Version"
---------------------------------------------------------------------
E :
S : Pointeur de chaine ASCIIZ
--------------------------------------------------------------------- */
const char *DATE_sver (void)
{
return VER;
}

/* ---------------------------------------------------------------------
DATE_sid()
---------------------------------------------------------------------
Role : Retourne une chaine "Identification"
---------------------------------------------------------------------
E :
S : Pointeur de chaine ASCIIZ
--------------------------------------------------------------------- */
const char *DATE_sid (void)
{
return ID;
}

/* ---------------------------------------------------------------------
DATE_annee4()
---------------------------------------------------------------------
Role : Conversion d'une date modulo 100 en date 4 digit
---------------------------------------------------------------------
E : date charniere
E : date sur 2 chiffres (0-99)
S : annee sur 4 chiffres
--------------------------------------------------------------------- */
int DATE_annee4 (int const yy, int const y2)
{
int y4;

ENUM_CHECK ();

if (y2 < (yy % 100))
{
y4 = y2 + ((yy / 100) + 1) * 100;
}
else
{
y4 = y2 + (yy / 100) * 100;
}
return y4;
}

/* ---------------------------------------------------------------------
DATE_jour_max()
---------------------------------------------------------------------
Role : Retourne le jour max en fonction de la date courante
---------------------------------------------------------------------
E : structure sDATE
S : jour 28/29/30/31
--------------------------------------------------------------------- */
int DATE_jour_max (sDATE * pDate)
{
int nod = 0;

ENUM_CHECK ();

is_valid (pDate, &nod);

return nod;
}

/* ---------------------------------------------------------------------
tm2DATE()
---------------------------------------------------------------------
Role : Conversion d'une date standard C en sDATE
---------------------------------------------------------------------
E : adresse de sortie (sDATE)
E : adresse de la date d'enytreee (struct tm)
S : 0=ok 1=err
--------------------------------------------------------------------- */
int tm2DATE (sDATE * const p_date, struct tm const *const p_tm)
{
int err = 0;

if (p_date && p_tm)
{
p_date->year = p_tm->tm_year + 1900;
p_date->month = p_tm->tm_mon + 1;
p_date->day = p_tm->tm_mday;

p_date->hour = p_tm->tm_hour;
p_date->minute = p_tm->tm_min;
p_date->second = p_tm->tm_sec;

err = !is_valid (p_date, NULL);
}
return err;
}

/* ---------------------------------------------------------------------
DATE2tm()
---------------------------------------------------------------------
Role : Conversion d'une date sDATE en standard C
---------------------------------------------------------------------
E : adresse de sortie (struct tm)
E : adresse de la date d'entree (sDATE)
S : 0=ok 1=err
--------------------------------------------------------------------- */
int DATE2tm (struct tm *const p_tm, sDATE const *const p_date)
{
int err = 0;

if (p_date && p_tm)
{
err = !is_valid (p_date, NULL);

if (!err)
{
p_tm->tm_year = p_date->year - 1900;
p_tm->tm_mon = p_date->month - 1;
p_tm->tm_mday = p_date->day;

p_tm->tm_hour = p_date->hour;
p_tm->tm_min = p_date->minute;
p_tm->tm_sec = p_date->second;

p_tm->tm_isdst = 0;

mktime (p_tm);
}
}
return err;
}

/* ---------------------------------------------------------------------
DATE_is_valid()
---------------------------------------------------------------------
Role : tester la validite d'une date
---------------------------------------------------------------------
E : structure date (sDATE)
S : 1=ok 0=err
--------------------------------------------------------------------- */
int DATE_is_valid (sDATE const *const pDate)
{
int ok;

ENUM_CHECK ();

if (pDate != NULL)
{
ok = is_valid (pDate, NULL);
}

return ok;
}

#ifdef DATE_PRINT
/* ----------------------------------------------------------------------
DATE_print()
----------------------------------------------------------------------

----------------------------------------------------------------------
E: structure interne de date
S:
---------------------------------------------------------------------- */
void DATE_print (sDATE const *const p_date)
{
static char const *const as_day[] {
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
};
struct tm tm_date;

int ok = !DATE2tm (&tm_date, p_date);

printf ("%s " DATE_FMT_FULL EOL
, ok ? as_day[tm_date.tm_wday] : "???"
, p_date->year
, p_date->month
, p_date->day
, p_date->hour
, p_date->minute
, p_date->second
);
}
#endif

#ifdef DATE_TM
/* ---------------------------------------------------------------------
DATE_tm_limites()
---------------------------------------------------------------------
OBSOLETE
Role : tester le limites d'une date
---------------------------------------------------------------------
E : structure standard date (tm)
S : 0=OK -1=KO
--------------------------------------------------------------------- */
int DATE_tm_limites (struct tm const *const p_tm)
{
int cr = -1;

ENUM_CHECK ();

if ((p_tm->tm_sec >= 0)
&& (p_tm->tm_sec < 60)
)
{
if ((p_tm->tm_min >= 0)
&& (p_tm->tm_min < 60)
)
{
if ((p_tm->tm_hour >= 0)
&& (p_tm->tm_hour < 24)
)
{
if ((p_tm->tm_mday > 0)
&& (p_tm->tm_mday <= 31)
)
{
if ((p_tm->tm_mon > 0)
&& (p_tm->tm_mon <= 12)
)
{
if ((p_tm->tm_year >= 0)
&& (p_tm->tm_year < 100)
)
{
cr = 0;
}
}
}
}
}
}

return cr;
}

/* ---------------------------------------------------------------------
DATE_tm_valide()
---------------------------------------------------------------------
OBSOLETE
Role : tester la validite d'une date
---------------------------------------------------------------------
E : structure standard date (tm)
S : 0=OK -1=KO
--------------------------------------------------------------------- */
int DATE_tm_valide (struct tm const *const p_tm)
{
int cr = -1;

ENUM_CHECK ();

if (p_tm != NULL)
{
cr = tm_is_valid (p_tm, NULL);
}

return cr;
}

/* ---------------------------------------------------------------------
DATE_tm_jour_max()
---------------------------------------------------------------------
OBSOLETE
Role : Retourne le jour max en fonction de la date courante
---------------------------------------------------------------------
E : structure standard date (tm)
S : jour 28/29/30/31
--------------------------------------------------------------------- */
int DATE_tm_jour_max (struct tm const *const p_tm)
{
int nod = 0;

ENUM_CHECK ();

tm_is_valid (p_tm, &nod);

return nod;
}

#if DATETIME2tm
/* ---------------------------------------------------------------------
DATE_Date2tm()
---------------------------------------------------------------------
OBSOLETE (tant que cette fonction utilise des DATE_tm*())

Role : Convertir une date au format __DATE__ au format tm
(les autres champs ne sont pas modifies)
---------------------------------------------------------------------
E : chaine sur __DATE__
E : structure standard date (tm)
S : 0=OK -1=KO
--------------------------------------------------------------------- */
int DATE_Date2tm (char const *s_date, struct tm *const p_tm)
{
int cr = -1;
struct tm date {0};
static char const *const as_months[] {
"Jan"
,"Feb"
,"Mar"
,"Apr"
,"May"
,"Jun"
,"Jul"
,"Aug"
,"Sep"
,"Oct"
,"Nov"
,"Dec"
};

ENUM_CHECK ();

if (s_date
&& (strlen (s_date) == sizeof szDATE - 1)
)
{
char *const sdup = STR_dup (s_date);
char *sbeg = sdup;
char *send = strstr (sbeg, SEP_D);

if (send)
{
*send = 0;
{
int n = STR_FindSz (as_months, NELEM (as_months), sbeg);

if (n != -1)
{
date.tm_mon = n + 1;
sbeg = send + strlen (SEP_D);

send = strstr (sbeg, SEP_D);

if (send)
{
*send = 0;

if (strlen (sbeg))
{
long l = strtol (sbeg, &send, 10);

if ((send != NULL)
&& (*send == 0)
)
{
date.tm_mday = (int) l;
sbeg = send + strlen (SEP_D);

l = strtol (sbeg, &send, 10);

if ((send != NULL)
&& (*send == 0)
)
{
date.tm_year = (int) l % 100;

cr = DATE_tm_limites (&date);

if (cr == 0)
{
date.tm_year = (int) l;

cr = tm_is_valid (&date, NULL);
}
}

}
}
}
}
}
}
free (sdup);
}

if ((cr == 0)
&& (p_tm))
{
p_tm->tm_mday = date.tm_mday;
p_tm->tm_mon = date.tm_mon;
p_tm->tm_year = date.tm_year;
}

return cr;
}

/* ---------------------------------------------------------------------
DATE_Time2tm()
---------------------------------------------------------------------
OBSOLETE (tant que cette fonction utilise des DATE_tm*())

Role : Convertir une heure au format __TIME__ au format tm
(les autres champs ne sont pas modifies)
---------------------------------------------------------------------
E : chaine sur __TIME__
E : structure standard date (tm)
S : 0=OK -1=KO
--------------------------------------------------------------------- */
int DATE_Time2tm (char const *s_time, struct tm *const p_tm)
{
int cr = -1;
struct tm date {0};

ENUM_CHECK ();

if ((s_time)
&& (strlen (s_time) == sizeof szTIME - 1)
)
{
char *const sdup = STR_dup (s_time);
char *sbeg = sdup;
char *send = strstr (sbeg, SEP_H);

if (send)
{
*send = 0;
{
long l = strtol (sbeg, &send, 10);

if ((send != NULL)
&& (*send == 0)
)
{
date.tm_hour = (int) l;
sbeg = send + strlen (SEP_H);

send = strstr (sbeg, SEP_H);

if (send)
{
*send = 0;
{
long l = strtol (sbeg, &send, 10);

if ((send != NULL)
&& (*send == 0)
)
{
date.tm_min = (int) l;
sbeg = send + strlen (SEP_H);

{
long l = strtol (sbeg, &send, 10);

if ((send != NULL)
&& (*send == 0)
)
{
date.tm_sec = (int) l;

}
}
}
}
}
}
}
}

free (sdup);
}

if (p_tm)
{
p_tm->tm_hour = date.tm_hour;
p_tm->tm_min = date.tm_min;
p_tm->tm_sec = date.tm_sec;
}

return cr;
}
#endif /* DATETIME2tm */

#endif /* DATE_TM */

/* public data ========================================================= */

/* File generated by 'NEW.EXE' Ver 1.20 (c) ED 1998-99 */



--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', "Antoine Leca" wrote:

Oublie fscanf() pour des entrées utilisateur, ce n'est pas
fait pour cela (et je n'ai aucune idée de pourquoi scanf()
peut bien exister).


Pour lire un fichier texte à partir d'un stdin redirigé!

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Eddahbi Karim

Moi, ca me parait bien. Y'a pas tant de mois differents. En admettant:

int day, month, year;

enum
{
JAN = 1,
FEV,
MAR,
AVR,
MAI,
JUN,
JUI,
AOU,
SEP,
OCT,
NOV,
DEC
};

switch (month)
{
case JAN:
case MAR:
case MAI:
case JUI:
case AOU:
case OCT:
case DEC:
if ((0 < day) || (day <= 31))
{
/* err: mauvais jour */
}
break;
case FEV:
if ((0 < day) || (day <= 28))
{
/* err: mauvais jour */
}
break;
case AVR:
case JUN:
case SEP:
case NOV:
if ((0 < day) || (day <= 30))
{
/* err: mauvais jour */
}
break;
default:
/*err: mauvais mois */
break;
}

non ?


Je vais tenter ça temporairement, et je vais voir si je peux pas
l'améliorer avec les astuces de Delahaye :)

Merci beaucoup,
Voila ;),
ThE_TemPLaR

1 2 3 4