IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

gérer les dates en c


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2012
    Messages : 25
    Par défaut gérer les dates en c
    Bonjour,

    Pourriez-vous m'éclairer sur la façon dont nous pouvons gérer la réservation de véhicules selon des dates je m'explique :

    Menu:

    Binevenu! pour résérver une voiture, laissez vous guider :

    date de départ :
    date de retour:
    le soucis est là : comment proposer ou intérpréter la saisie des dates ?

    merci de votre aide

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Bonjour,

    La gestion d'une saisie fiable, en C, est toujours compliquée à mettre en place.

    Cela dit, tu peux utiliser scanf() si tu es sûre que l'utilisateur respectera scrupuleusement le format de saisie. Sinon, tu peux passer par un fgets() et plusieurs strtol() pour le jour, le mois et l'année.

    Enfin, tu peux encadrer le tout dans une boucle dowhile qui te permette d'écrire : « erreur : veuillez recommencer » si la date saisie est mauvaise. Enfin, tu placeras le tout dans une fonction dédiée qui te permettra à tout moment de saisir une date et qui t'évitera d'avoir à réécrire la même chose lorsque tu saisiras la date de retour.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 793
    Billets dans le blog
    1
    Par défaut
    Salut
    Déjà je commencerais par créer une fonction dédiée à vérifier que la date est valide ou pas. Un truc du style
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int verif_date (int jj, int mm, int aa)
    {
        si jj > 31 return 0;
        si mm > 12 return 0;
        si jj == 31 && (mm == 2 or mm == 4 ...) return 0;
        si jj == 30 && mm == 2 return 0;
        si jj == 29 && mm == 2 && aa ... return 0;
        ...
        return 1;
    }

    Ensuite tu fais saisir la date via fgets() et tu extraits jj, mm et aa via fscanf. Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    char chaine[12];  // 10 caractères pour jj/mm/aaaa + le <return> + le '\0'
    int jj, mm, aa;
     
    while (1)
    {
        printf("Entrez la date sous la forme jj/mm/aaaa :"); fflush(stdout);
        fgets(chaine, 12, stdin);
        if (fscanf(chaine, "%d/%d/%d", &jj, &mm, &aa) == 3 && verif_date(jj, mm, aa)) break;
        printf("Date incorrecte - Recommencez\n");
    }
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    La gestion d'une saisie fiable, en C, est toujours compliquée à mettre en place.
    Salut,

    Ça c'est vrai. Ensuite tout va dépendre de l’environnement :

    1. Terminal
      Le plus difficile ...
      soit on force en décomposant la saisie de la date en la saisie du jour puis du mois puis de l'année (c'est clair et évite d'avoir à parser une chaine)
      soit on lit une chaine et on la parse avec toute la gestion des erreurs, quoiqu'il me semble que la libc standard fournisse des fonctions qui simplifient la vie ... à vérifier
      sinon il y a les formulaires de type ncurse mais bon ... l'investissement dans ce genre d'interface est généralement inutile.
    2. GUI
      a priori le plus facile : il y a toujours un composant qui t'évite la saisie d'une date impossible (29/02/1900 par exemple, mais moins souvent le 10 décembre 1582 en France), d'une manière plus ou moins pratique (champs de saisis valdant / calendrier déroulant / ...)




    EDIT: Pas de fonctions standards pour la conversion chaine -> type date dans la norme ISO. Néanmoins, posix définit strptime et getdate. La première semble plus simple d'emploi.

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Citation Envoyé par kwariz Voir le message
    • GUI
      a priori le plus facile : il y a toujours un composant qui t'évite la saisie d'une date impossible (29/02/1900 par exemple, mais moins souvent le 10 décembre 1582 en France), d'une manière plus ou moins pratique (champs de saisis valdant / calendrier déroulant / ...)
    Entièrement d'accord mais, apparemment, le primo-postant débute et, de toutes évidences, il réalise un programme en mode console. Donc…

  6. #6
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2012
    Messages : 25
    Par défaut
    Bonjour,

    Merci à tous pour vos réponses. J'ai fini par écrire en C la version d'un Algo qui permet d'avoir une date valide selon les mois, les jours et les années (bissextiles).
    Voici la bonne version du code qui marche nickel


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    int verifdate(int jour, int mois, int annee){ 
     
    	int B= ((annee%4 == 0) && (annee%100 !=0) || (annee%400==0));
    	int K1= ((mois==1 || mois==3 || mois==5 || mois==7 || 		mois==8 || mois==10 || mois==12) && (jour>=1 && jour<=31));
    	int K2=((mois==4 || mois==6 || mois==9 || mois==11) && 		(jour>=1 && jour<=30));
    	int K3= ((mois==2 || B) && (jour>=1 && jour<=29));
    	int K4= (mois==2 && jour>=1 && jour<=28);
     
     
    	if (K1 || K2 || K3 || K4){
    		return 0;
    		}
    	else{
    		return 1;	
    		}
    }

  7. #7
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Salut,

    La fonction que tu viens d'écrire est bien, mais ce n'est que la vérification "finale"... Une fois que tout le reste fonctionne. Par "tout le reste", j'entends la saisie du jour, du mois, de l'année (en France, car l'ordre dépend bien sûr du pays), ainsi que la vérification que les données saisies sont bien des entiers. Bonne continuation.

    A+

    Pfeuh

    P.S. Je trouve que ta fonction manque un peu de lisibilité, si je peux me permettre. C'est un paramètre important, surtout quand il s'agit de trouver un bug. Ci dessous une suggestion. Je n'ai pas spécialement vérifié tous les tests, et peut être verras tu l'intérêt de la macro assert.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    #include <stdlib.h>
    #include <stdio.h>
    #include <assert.h>
     
    int dateIsValid(int jour, int mois, int annee)
    {
        int result = 1; /* on part en supposant que tout est juste */
        int bissextile = (annee%4 == 0) && ((annee%100 !=0) || (annee%400==0));
     
        if(jour < 1)
            result = 0;
        else
        {
            switch(mois)
            {
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    if(jour > 31)
                        result = 0;
                    break;
                case 4:
                case 6:
                case 9:
                case 11:
                    if(jour > 30)
                        result = 0;
                    break;
                case 2:
                    if(bissextile != 0)
                    {
                        if(jour > 29)
                            result = 0;
                    }
                    else
                        if(jour > 28)
                            result = 0;
                    break;
                default:
                    result = 0;
            }
        }
        return result;
    }
     
    int main (void)
    {
        assert(dateIsValid(31, 3, 2012) == 1);
        assert(dateIsValid(32, 3, 2012) == 0);
        assert(dateIsValid(29, 2, 2012) == 1);
        assert(dateIsValid(30, 2, 2012) == 0);
        assert(dateIsValid(29, 2, 2011) == 0);
     
        return 0;
    }

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 793
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par edmr_ps Voir le message
    Voici la bonne version du code qui marche nickel


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    int verifdate(int jour, int mois, int annee){ 
     
    	int B= ((annee%4 == 0) && (annee%100 !=0) || (annee%400==0));
    	int K1= ((mois==1 || mois==3 || mois==5 || mois==7 || 		mois==8 || mois==10 || mois==12) && (jour>=1 && jour<=31));
    	int K2=((mois==4 || mois==6 || mois==9 || mois==11) && 		(jour>=1 && jour<=30));
    	int K3= ((mois==2 || B) && (jour>=1 && jour<=29));
    	int K4= (mois==2 && jour>=1 && jour<=28);
     
     
    	if (K1 || K2 || K3 || K4){
    		return 0;
    		}
    	else{
    		return 1;	
    		}
    }
    Dommage, tu effectues tous les calculs tout le temps même les calculs inutiles comme par exemple vérifier si l'année est bissextile alors que cela ne se justifie que dans le cadre d'un 29 février. Et en plus les calculs K3 et K4 sont très similaires...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int verifdate(int jour, int mois, int annee){ 
     
    	if (jour >= 1 && jour <= 28) return 1;
    	if ((mois==1 || mois==3 || mois==5 || mois==7 || mois==8 || mois==10 || mois==12) && jour<=31)) return 1;
    	if ((mois==4 || mois==6 || mois==9 || mois==11) && jour<=30)) return 1;
    	if (mois==2 && jour == 29 && ((annee%4 == 0) && (annee%100 !=0) || (annee%400==0))) return 1;
    	return 0;
    }
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. [Modèle Relationnel] comment gérer les dates d'échéance
    Par akara dans le forum Schéma
    Réponses: 7
    Dernier message: 18/04/2009, 00h56
  2. Réponses: 13
    Dernier message: 07/02/2007, 12h10
  3. [Dates] Comment gérer les dates sur un blog ?
    Par psychoBob dans le forum Langage
    Réponses: 10
    Dernier message: 14/06/2006, 14h09
  4. Gérer les dates avec SQL Server 2000
    Par saby dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 25/01/2006, 18h06
  5. [Modèle Relationnel] gérer les dates
    Par allowen dans le forum Schéma
    Réponses: 10
    Dernier message: 13/10/2004, 19h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo