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 :

Problème et AVC : _wfopen_s


Sujet :

C++

  1. #281
    Nouveau Candidat au Club Avatar de Laurent_B_
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2021
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 512
    Points : 0
    Points
    0
    Par défaut
    Bonsoir bacelar,

    Film : Avatar et cinema.cpp
    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    ...
    class exception_date_year
    {
    	std::wstring message;
    public:
    	exception_date_year() : message(L"L'année illégale doit être l'année numérique - entre 1900 et 3001") {}
    	std::wstring get_message() const { return message; }
    };
     
    void test_date_year(int& year)
    {
    	if (year <= 1900 || year >= 3001)
    	{
    		throw exception_date_year();
    	}
    	return;
    }
     
    class exception_date_month
    {
    	std::wstring message;
    public:
    	exception_date_month() : message(L"Le mois illégal doit être un mois numérique - entre 1 et 12") {}
    	std::wstring get_message() const { return message; }
    };
     
    void test_date_month(int& month)
    {
    	if (month <= 0 || month >= 13)
    	{
    		throw exception_date_month();
    	}
    	return;
    }
     
    class exception_date_day
    {
    	std::wstring message;
    public:
    	exception_date_day() : message(L"Le jour illégal doit être un jour numérique - entre 1 et 31") {}
    	std::wstring get_message() const { return message; }
    };
     
    void test_date_day(int& day)
    {
    	if (day <= 0 || day >= 32)
    	{
    		throw exception_date_day();
    	}
    	return;
    }
     
    class exception_date_tire_sp_etc
    {
    	std::wstring message;
    public:
    	exception_date_tire_sp_etc() : message(L"aaaaaaaaaa") {}
    	std::wstring get_message() const { return message; }
    };
     
    void test_date_tire_sp_etc(wchar_t d)
    {
    	if (d != L'-' && d != L'/' && d != L'.' && d != L' ')
    	{
    		throw exception_date_tire_sp_etc();
    	}
    	return;
    }
    ...
    const void Cinema::afficher_Date_de_reprise_ou_de_sortie(std::wstring& d_filename, const std::wstring& nomFichier)
    { // Date de reprise
    	assert((d_filename == createdBy_filename) && L"Erreur !!! Date de reprise... !");
    	std::wstring d = lire_fichierTxt(nomFichier);
    	std::size_t pos = 0;
    	// year
    	int year = 0;
    	year = std::stoi(d, &pos);
    	try
    	{
    		test_date_year(year);
    	}
    	catch (exception_date_year e)
    	{
    		std::wcout << L"Exception a été capturée : " << e.get_message() << std::endl;
    		exit(1);
    	}
    	d = d.substr(4);
    	// date_tire_sp_etc
    	try
    	{
    		test_date_tire_sp_etc(d[0]);
    	}
    	catch (exception_date_tire_sp_etc e2)
    	{
    		std::wcout << L"Exception a été capturée : " << e2.get_message() << std::endl;
    		exit(1);
    	}
    	d = d.substr(1);
    	// mon
    	int mon = 0;
    	pos = 0;
    	mon = std::stoi(d, &pos);
    	try
    	{
    		test_date_month(mon);
    	}
    	catch (exception_date_month e3)
    	{
    		std::wcout << L"Exception a été capturée : " << e3.get_message() << std::endl;
    		exit(1);
    	}
    	d = d.substr(2);
    	// date_tire_sp_etc
    	try
    	{
    		test_date_tire_sp_etc(d[0]);
    	}
    	catch (exception_date_tire_sp_etc e2)
    	{
    		std::wcout << L"Exception a été capturée : " << e2.get_message() << std::endl;
    		exit(1);
    	}
    	d = d.substr(1);
    	// mday
    	int mday = 0;
    	mday = std::stoi(d, &pos);
    	try
    	{
    		test_date_day(mday);
    	}
    	catch (exception_date_day e4)
    	{
    		std::wcout << L"Exception a été capturée : " << e4.get_message() << std::endl;
    		exit(1);
    	}
    	//
    	std::tm date;
    	date.tm_year = year - 1900;
    	date.tm_mon = mon - 1;
    	date.tm_mday = mday;
    	if (d_filename == L"Date de reprise.txt")
    		date_de_reprise = date;
    	else
    		date_de_sortie = date;
    	}
    ...
    Ok ou pas ?

    Merci beaucoup ;-)

  2. #282
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 291
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 291
    Points : 1 889
    Points
    1 889
    Par défaut
    Une exception pour détecter les erreurs de saisie utilisateur, WTF ?

  3. #283
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 139
    Points : 12 239
    Points
    12 239
    Par défaut
    Citation Envoyé par Laurent_B_ Voir le message
    Bonsoir bacelar,
    ...
    Merci énormément

    Donc, quelles sont ces règles ?
    Ah ! Mince ! Tant pis ! Plus tard
    C'est dommage.

    Il serait plus constructif de voir comment faire "correctement" à une fonctionnalité plutôt que d'essayer de comprendre un code très très mal écrit qui fait 10 choses en même temps.


    Explique-moi ?
    Expliquer un code horriblement complexe pour faire pas grand-chose ??? (et il manque un bout)

    Pour moi, cette horreur ne fait que (et très très mal) :
    - lire le contenu d'un fichier
    - interprète le contenu de ce fichier sous forme d'une chaîne de caractère contenant 3 nombres pour le numéro d'année , du numéro de mois et de numéro du jour séparé par une farandole de séparateur
    - "vérifie" que la date obtenue est valide pour une date du calendrier grégorien (enfin je l'interprète comme ça).
    - modifie l'une des 2 variables date_de_reprise ou date_de_sortie, mais jamais les 2. J'espère que c'est des champs de la classe (donc faudrait un préfixe "m_") et pas de variables globales ou statiques à la con.

    Déjà, c'est 4 trucs, donc 3 de trop.

    Et, comme d'habitude, le nom de la fonction n'a rien à voir avec ce qu'elle fait réellement (même si c'était la cas, purée que le nom serait compliquée => fait trop de chose).
    EDIT: après avoir jeté un coup d’œil au GitHub, cette fonction horrifique ("afficher_Date_de_reprise_ou_de_sortie") n'y est pas mais "afficher_Date_de_reprise" y est et elle est du même acabit.
    Si on calque la fin de cette dernière ("afficher_Date_de_reprise"), la fonction "afficher_Date_de_reprise_ou_de_sortie" a un nom un peu plus logique, car elle ferait bien un affichage à la fin.
    C'est donc un 5ème trucs qu'elle ferait, donc les 4 autres serait de trop.


    Vous voulez vraiment qu'on disserte sur des dizaines de lignes sur un machin qu'on ne devrait jamais écrire ???

    Si on fait les choses biens, on découpe le travail en tache simple.

    Déjà "lire le contenu d'un fichier", ça a dû être fait ailleurs de manière bien plus propre.
    Donc les paramètres "d_filename" et "nomFichier", qui portent quasiment le même nom, preuve que c'est pas très malin, on les dégage.
    La seule chose qui nous intéresse en entrée, c'est le contenu du fichier, donc on passe en paramètre seulement une "const std::wstring" directement avec le contenu du fichier (qui a été bien "mieux" récupéré avant dans le processus).
    Déterminer les 3 valeurs constituants une date dans une chaîne de caractère, une simple "expression régulière" fera le travail de manière bien plus claire concise que l'horreur du code de "Cinema::afficher_Date_de_reprise_ou_de_sortie"
    Déterminer qu'un triplet de nombre est une date valide dans le calendrier grégorien, si c'est pas dans le standard, ça doit exister sur le net : Google est mon ami:
    Question posée :
    how to verify date in C++
    Premier résultat :
    http://www.zedwood.com/article/cpp-checkdate-function-date-validation#:~:text=One%20of%20the%20nice%20functions,months%20coming%20from%20user%20input.


    La fonction checkdate qui y est présenté me semble très correcte :
    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
    bool checkdate(int m, int d, int y)
    {
      //gregorian dates started in 1582
      if (! (1582<= y )  )//comment these 2 lines out if it bothers you
         return false;
      if (! (1<= m && m<=12) )
         return false;
      if (! (1<= d && d<=31) )
         return false;
      if ( (d==31) && (m==2 || m==4 || m==6 || m==9 || m==11) )
         return false;
      if ( (d==30) && (m==2) )
         return false;
      if ( (m==2) && (d==29) && (y%4!=0) )
         return false;
      if ( (m==2) && (d==29) && (y%400==0) )
         return true;
      if ( (m==2) && (d==29) && (y%100==0) )
         return false;
      if ( (m==2) && (d==29) && (y%4==0)  )
         return true;
     
      return true;
    }
    S'il y a des problèmes avec, on n'aura à corriger qu'à un seul endroit.

    La modification de "une des 2 variables..." c'est tellement pourri qu'on pourra faire mieux.

    EDIT: pour l'affichage, le 5ème trucs qu'on devine avec le code complet de "afficher_Date_de_reprise" dans GitHub , et qui serait raccord avec le nom de la fonction, faut pas mélanger l'acquisition/vérification des données (les 3 premières tâches de cette fonction trop longue) et l'affichage.
    L'affichage en lui-même est tellement bateau qu'une fonction dédiée serait peut-être overkill.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void Cinema::afficherDateRepriseOuSortie(){
        afficherDate(m_dateReprise!=nullptr ? m_dateReprise : m_dateSortie);
    }
     
    void Cinema::afficherDate(const& myDate date){
    ... //mise en forme d'une date selon les règles d'affichage ad hoc
        PrintTmp(...);
    ...
    }


    Je vais donner une implémentation simple d'une fonction qui se charge du décodage d'une chaîne de caractère contenant une date, plus simplement, plus facile à maintenir, plus souple, etc... que cette horreur de "Cinema::afficher_Date_de_reprise_ou_de_sortie":
    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
    #include <regex>
    #include <iostream>
    ....
     
    std::tm Cinema::ParseDate(std::wstring& str)
    {
    	//le seul truc non trivial est l'utilisation d'une expression régulière, Google est notre ami.
    	std::wregex date_regex(L"(\\d{4})(?:/|\\-|\\.|\\s)(\\d{2})(?:/|\\-|\\.|\\s)(\\d{2})");
    	std::wsmatch matches;
     
    	if (std::regex_search(str, matches, date_regex))
    	{
    		int year	= std::stoi(matches[1].str());
    		int month	= std::stoi(matches[2].str());
    		int day	= std::stoi(matches[3].str());
     
    		if(checkdate(month,day,year)
    		{
    			std::tm date;
    			date.tm_year = year - 1900;
    			date.tm_mon = month - 1;
    			date.tm_mday = day;
     
    			return date;
    		}
    		else
    		{
    			throw std::invalid_argument("Cinema::ParseDate : La date passée en argument n'est pas valide.")
    		}
    	}
    	else
    	{
    		throw std::invalid_argument("Cinema::ParseDate : Le format de l'argument n'est pas valide.")
    	}
    }
    ...
    Je vais donc essayer de ne pas m'attarder sur tous les problèmes dans la fonction "Cinema::afficher_Date_de_reprise_ou_de_sortie" qui à comparer avec la fonction "Cinema:: ParseDate" est un capharnaüm labyrinthique.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const void Cinema::afficher_Date_de_reprise_ou_de_sortie(std::wstring& d_filename, const std::wstring& nomFichier)
    C'est quoi ce "const", le compilateur devrait vous dire que c'est nimpornawak.
    On passe sur le nom de la fonction qui n'a rien à voir avec ce qu'elle sensée faire.
    2 paramètres quasi-identique, qui ne servent à rien à cause de l'assert à la ligne 3 : "assert((d_filename == createdBy_filename) && L"Erreur !!! Date de reprise... !");"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    assert((d_filename == createdBy_filename) && L"Erreur !!! Date de reprise... !");
    Ca vérifie que le paramètre "d_filename" a bien pour valeur la même valeur que la variable globale/champ statique de la classe/autre connerie de variable à la con "createdBy_filename" sinon lance une exception avec le message "Erreur !!! Date de reprise... !".
    Donc les paramètres "d_filename " et "nomFichier" ne servent à rien car la fonction n'est pas paramétrable (au sens mathématique de la chose).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::wstring d = lire_fichierTxt(nomFichier);
    On remplit "d" avec le contenu du fichier dont le nom est la valeur du paramètre "nomFichier".
    "d" comme nom de variable, il y a de l'abus!
    C'est un truc qui n'a rien de spécifique à la fonction, autant le faire à l'extérieur de la fonction, avec des fonctions bien plus généralistes.

    Encore une variable avec un nom à la con, qui va servir à 100 choses différentes.
    Dégagez ce type de variable et déclarez une variable par usage.
    Et la valeur par défaut raisonnable d'un std::size_t pour une position dans un chaîne, c'est "std:: string:: npos", pas 0 (et "std:: string:: npos", c'est bien souvent -1 mais jamais 0).

    Donc le code suivant,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	std::size_t pos = 0;
     
    	// year
    	int year = 0;
    	year = std::stoi(d, &pos);
    devrait être, pour être un minimum maintenable:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::size_t year_len;
    	int year = std::stoi(d, &year_len);
    et encore, comme vous vous foutez de la longueur de vos suites de chiffres, un code aussi simple que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int year = std::stoi(d);
    fait aussi bien et tout aussi "robuste" (c'est un sarcasme).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    try
    	{
    		if (year <= 1900 || year >= 3001)
    		{
    			throw std::wstring(L"L'année illégale doit être l'année numérique - entre 1900 et 3001");
    		}
    	}
    	catch (runtime_error const& exception)
    	{
    		std::wcout << L"Erreur : " << exception.what() << std::endl;
    	}
    Tout ce code juste pour envoyer sur la console un message d'erreur si year est compris entre 1900 et 3001 inclus.
    Le calendrier grégorien est valide à partir de 1582, le cinéma a été inventé avant 1900.
    Et c'est quoi qui arrive en 3001 ? Le nouvel Apocalypse selon Paco Rabane ?
    cf. la fonction "checkdate " trouvée sur le net et postée ci-avant dans ce post.

    Même si cette contrainte est foireuse, le code suivant fait strictement la même chose mais en plus direct :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (year <= 1900 || year >= 3001)
    		{
    			std::wcout << L"Erreur : L'année illégale doit être l'année numérique - entre 1900 et 3001" << std::endl;
    		}
    Lancer une exception qu'on capture (via catch) systématiquement dans la même méthode n'a aucun putain d'intérêt.

    là, on va juste faire en sorte de supprimer de d les 4 premiers caractère.
    Donc, pourquoi s'emmerder à passer la variable "pos" en ligne 9 ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    year = std::stoi(d, &pos);
    Donc on supprime les 4 caractères représentant putativement l'année dans la chaîne de caractère "d" contenant le contenu du fichier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::wcout << L"-/. ={" << d[0] << L"}" << std::endl;
    Affiche dans la console le caractère en début de chaîne "d", donc le cinquième du fichier suite à l'exécution de la ligne 21 de votre code.
    En l'encadrant devant par la chaîne "-/. ={", et derrière avec "}".
    J'ai déjà indiqué plus d'une fois que faire des traces de débogage dans le console est une énorme CONNERIE.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    try
    	{
    		if (d[0] == L'-' || d[0] == L'/' || d[0] == L'.' || d[0] == L' ')
    		{
    			throw std::wstring(L"Illegal aaaaaaaa");
    		}
        }
    	catch (runtime_error const& exception)
    	{
    		std::wcout << L"Erreur : " << exception.what() << std::endl;
    	}
    	d = d.substr(1);
    Même conneries qu'aux lignes 10 à 21.
    Là on vérifie juste que le 5ème caractère dans le fichier est soit "-" soit "/" soit "." soit un espace, sinon, on envoie encode des cochonneries dans la console.

    Les lignes 36 à 79, c'est 2 fois les mêmes bêtises que les lignes 5 à 35 mais en cherchant le numéro de mois et le numéro de jours et en y faisant des vérifications complètement bancales.
    cf. le code de la fonction "checkdate" qui fait tout cela de manière bien plus simple et correcte.

    Les lignes 80 à 83, on initialise la variable "date", de type std::tm ( cf. https://en.cppreference.com/w/cpp/chrono/c/tm) avec les informations glanées dans les lignes précédentes.

    Les lignes 84 à 88, en fonction de la valeur de la variable "d_filename", soit on initialise la variable "date_de_reprise", soit la variable "date_de_sortie". (C'est complètement bancal comme approche.)

  4. #284
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 139
    Points : 12 239
    Points
    12 239
    Par défaut
    Citation Envoyé par Laurent_B_ Voir le message
    Bonsoir bacelar,
    ...
    Merci beaucoup ;-)
    Vous isolez des fonctionnalités dans des fonctions, c'est bien.
    Mais il faut correctement calibrer ces fonctionnalités.
    Pour savoir si une date est valide, il faut tous les paramètres (année, mois, jour), ne pas copier les conneries initiales, SVP.

    Avoir plusieurs classes d'exception n'a de sens que si les traitements de ces différents types d'exceptions est différente, ce qui n'est pas le cas. Une simple "std::invalid_argument" devrait largement faire l'affaire, au moins pour l'instant.

    Vous nous collez 146 lignes de code inutilement complexe et fragile quand 2 fonctions de 20 lignes font largement aussi bien le taffe (même beaucoup mieux).

  5. #285
    Nouveau Candidat au Club Avatar de Laurent_B_
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2021
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 512
    Points : 0
    Points
    0
    Par défaut
    Bonsoir,

    C'est dommage.

    Il serait plus constructif de voir comment faire "correctement" à une fonctionnalité plutôt que d'essayer de comprendre un code très très mal écrit qui fait 10 choses en même temps.


    Explique-moi ?
    Expliquer un code horriblement complexe pour faire pas grand-chose ??? (et il manque un bout)

    Pour moi, cette horreur ne fait que (et très très mal) :
    - lire le contenu d'un fichier
    - interprète le contenu de ce fichier sous forme d'une chaîne de caractère contenant 3 nombres pour le numéro d'année , du numéro de mois et de numéro du jour séparé par une farandole de séparateur
    - "vérifie" que la date obtenue est valide pour une date du calendrier grégorien (enfin je l'interprète comme ça).
    - modifie l'une des 2 variables date_de_reprise ou date_de_sortie, mais jamais les 2. J'espère que c'est des champs de la classe (donc faudrait un préfixe "m_") et pas de variables globales ou statiques à la con.

    Déjà, c'est 4 trucs, donc 3 de trop.

    Et, comme d'habitude, le nom de la fonction n'a rien à voir avec ce qu'elle fait réellement (même si c'était la cas, purée que le nom serait compliquée => fait trop de chose).
    EDIT: après avoir jeté un coup d’œil au GitHub, cette fonction horrifique ("afficher_Date_de_reprise_ou_de_sortie") n'y est pas mais "afficher_Date_de_reprise" y est et elle est du même acabit.
    Si on calque la fin de cette dernière ("afficher_Date_de_reprise"), la fonction "afficher_Date_de_reprise_ou_de_sortie" a un nom un peu plus logique, car elle ferait bien un affichage à la fin.
    C'est donc un 5ème trucs qu'elle ferait, donc les 4 autres serait de trop.


    Vous voulez vraiment qu'on disserte sur des dizaines de lignes sur un machin qu'on ne devrait jamais écrire ???

    Si on fait les choses biens, on découpe le travail en tache simple.

    Déjà "lire le contenu d'un fichier", ça a dû être fait ailleurs de manière bien plus propre.
    Donc les paramètres "d_filename" et "nomFichier", qui portent quasiment le même nom, preuve que c'est pas très malin, on les dégage.
    La seule chose qui nous intéresse en entrée, c'est le contenu du fichier, donc on passe en paramètre seulement une "const std::wstring" directement avec le contenu du fichier (qui a été bien "mieux" récupéré avant dans le processus).
    Déterminer les 3 valeurs constituants une date dans une chaîne de caractère, une simple "expression régulière" fera le travail de manière bien plus claire concise que l'horreur du code de "Cinema::afficher_Date_de_reprise_ou_de_sortie"
    Déterminer qu'un triplet de nombre est une date valide dans le calendrier grégorien, si c'est pas dans le standard, ça doit exister sur le net : Google est mon ami:
    Question posée :
    how to verify date in C++
    Premier résultat :
    http://www.zedwood.com/article/cpp-c...20user%20input.


    La fonction checkdate qui y est présenté me semble très correcte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part

    bool checkdate(int m, int d, int y)
    {
    //gregorian dates started in 1582
    if (! (1582<= y ) )//comment these 2 lines out if it bothers you
    return false;
    if (! (1<= m && m<=12) )
    return false;
    if (! (1<= d && d<=31) )
    return false;
    if ( (d==31) && (m==2 || m==4 || m==6 || m==9 || m==11) )
    return false;
    if ( (d==30) && (m==2) )
    return false;
    if ( (m==2) && (d==29) && (y%4!=0) )
    return false;
    if ( (m==2) && (d==29) && (y%400==0) )
    return true;
    if ( (m==2) && (d==29) && (y%100==0) )
    return false;
    if ( (m==2) && (d==29) && (y%4==0) )
    return true;

    return true;
    }
    S'il y a des problèmes avec, on n'aura à corriger qu'à un seul endroit.

    La modification de "une des 2 variables..." c'est tellement pourri qu'on pourra faire mieux.

    EDIT: pour l'affichage, le 5ème trucs qu'on devine avec le code complet de "afficher_Date_de_reprise" dans GitHub , et qui serait raccord avec le nom de la fonction, faut pas mélanger l'acquisition/vérification des données (les 3 premières tâches de cette fonction trop longue) et l'affichage.
    L'affichage en lui-même est tellement bateau qu'une fonction dédiée serait peut-être overkill.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part

    void Cinema::afficherDateRepriseOuSortie(){
    afficherDate(m_dateReprise!=nullptr ? m_dateReprise : m_dateSortie);
    }

    void Cinema::afficherDate(const& myDate date){
    ... //mise en forme d'une date selon les règles d'affichage ad hoc
    PrintTmp(...);
    ...
    }


    Je vais donner une implémentation simple d'une fonction qui se charge du décodage d'une chaîne de caractère contenant une date, plus simplement, plus facile à maintenir, plus souple, etc... que cette horreur de "Cinema::afficher_Date_de_reprise_ou_de_sortie":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part

    #include <regex>
    #include <iostream>
    ....

    std::tm Cinema:arseDate(std::wstring& str)
    {
    //le seul truc non trivial est l'utilisation d'une expression régulière, Google est notre ami.
    std::wregex date_regex(L"(\\d{4})(?:/|\\-|\\.|\\s)(\\d{2})(?:/|\\-|\\.|\\s)(\\d{2})");
    std::wsmatch matches;

    if (std::regex_search(str, matches, date_regex))
    {
    int year = std::stoi(matches[1].str());
    int month = std::stoi(matches[2].str());
    int day = std::stoi(matches[3].str());

    if(checkdate(month,day,year)
    {
    std::tm date;
    date.tm_year = year - 1900;
    date.tm_mon = month - 1;
    date.tm_mday = day;

    return date;
    }
    else
    {
    throw std::invalid_argument("Cinema:arseDate : La date passée en argument n'est pas valide.")
    }
    }
    else
    {
    throw std::invalid_argument("Cinema:arseDate : Le format de l'argument n'est pas valide.")
    }
    }
    ...
    Je vais donc essayer de ne pas m'attarder sur tous les problèmes dans la fonction "Cinema::afficher_Date_de_reprise_ou_de_sortie" qui à comparer avec la fonction "Cinema:: ParseDate" est un capharnaüm labyrinthique.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const void Cinema::afficher_Date_de_reprise_ou_de_sortie(std::wstring& d_filename, const std::wstring& nomFichier)
    C'est quoi ce "const", le compilateur devrait vous dire que c'est nimpornawak.
    On passe sur le nom de la fonction qui n'a rien à voir avec ce qu'elle sensée faire.
    2 paramètres quasi-identique, qui ne servent à rien à cause de l'assert à la ligne 3 : "assert((d_filename == createdBy_filename) && L"Erreur !!! Date de reprise... !");"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    assert((d_filename == createdBy_filename) && L"Erreur !!! Date de reprise... !");
    Ca vérifie que le paramètre "d_filename" a bien pour valeur la même valeur que la variable globale/champ statique de la classe/autre connerie de variable à la con "createdBy_filename" sinon lance une exception avec le message "Erreur !!! Date de reprise... !".
    Donc les paramètres "d_filename " et "nomFichier" ne servent à rien car la fonction n'est pas paramétrable (au sens mathématique de la chose).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::wstring d = lire_fichierTxt(nomFichier);
    On remplit "d" avec le contenu du fichier dont le nom est la valeur du paramètre "nomFichier".
    "d" comme nom de variable, il y a de l'abus!
    C'est un truc qui n'a rien de spécifique à la fonction, autant le faire à l'extérieur de la fonction, avec des fonctions bien plus généralistes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::size_t pos = 0;
    Encore une variable avec un nom à la con, qui va servir à 100 choses différentes.
    Dégagez ce type de variable et déclarez une variable par usage.
    Et la valeur par défaut raisonnable d'un std::size_t pour une position dans un chaîne, c'est "std:: string:: npos", pas 0 (et "std:: string:: npos", c'est bien souvent -1 mais jamais 0).

    Donc le code suivant,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::size_t pos = 0;

    // year
    int year = 0;
    year = std::stoi(d, &pos);
    devrait être, pour être un minimum maintenable:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::size_t year_len;
    int year = std::stoi(d, &year_len);
    et encore, comme vous vous foutez de la longueur de vos suites de chiffres, un code aussi simple que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int year = std::stoi(d);
    fait aussi bien et tout aussi "robuste" (c'est un sarcasme).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part

    try
    {
    if (year <= 1900 || year >= 3001)
    {
    throw std::wstring(L"L'année illégale doit être l'année numérique - entre 1900 et 3001");
    }
    }
    catch (runtime_error const& exception)
    {
    std::wcout << L"Erreur : " << exception.what() << std::endl;
    }
    Tout ce code juste pour envoyer sur la console un message d'erreur si year est compris entre 1900 et 3001 inclus.
    Le calendrier grégorien est valide à partir de 1582, le cinéma a été inventé avant 1900.
    Et c'est quoi qui arrive en 3001 ? Le nouvel Apocalypse selon Paco Rabane ?
    cf. la fonction "checkdate " trouvée sur le net et postée ci-avant dans ce post.

    Même si cette contrainte est foireuse, le code suivant fait strictement la même chose mais en plus direct :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (year <= 1900 || year >= 3001)
    {
    std::wcout << L"Erreur : L'année illégale doit être l'année numérique - entre 1900 et 3001" << std::endl;
    }
    Lancer une exception qu'on capture (via catch) systématiquement dans la même méthode n'a aucun putain d'intérêt.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    d = d.substr(4);
    là, on va juste faire en sorte de supprimer de d les 4 premiers caractère.
    Donc, pourquoi s'emmerder à passer la variable "pos" en ligne 9 ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    year = std::stoi(d, &pos);
    Donc on supprime les 4 caractères représentant putativement l'année dans la chaîne de caractère "d" contenant le contenu du fichier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::wcout << L"-/. ={" << d[0] << L"}" << std::endl;
    Affiche dans la console le caractère en début de chaîne "d", donc le cinquième du fichier suite à l'exécution de la ligne 21 de votre code.
    En l'encadrant devant par la chaîne "-/. ={", et derrière avec "}".
    J'ai déjà indiqué plus d'une fois que faire des traces de débogage dans le console est une énorme CONNERIE.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part

    try
    {
    if (d[0] == L'-' || d[0] == L'/' || d[0] == L'.' || d[0] == L' ')
    {
    throw std::wstring(L"Illegal aaaaaaaa");
    }
    }
    catch (runtime_error const& exception)
    {
    std::wcout << L"Erreur : " << exception.what() << std::endl;
    }
    d = d.substr(1);
    Même conneries qu'aux lignes 10 à 21.
    Là on vérifie juste que le 5ème caractère dans le fichier est soit "-" soit "/" soit "." soit un espace, sinon, on envoie encode des cochonneries dans la console.

    Les lignes 36 à 79, c'est 2 fois les mêmes bêtises que les lignes 5 à 35 mais en cherchant le numéro de mois et le numéro de jours et en y faisant des vérifications complètement bancales.
    cf. le code de la fonction "checkdate" qui fait tout cela de manière bien plus simple et correcte.

    Les lignes 80 à 83, on initialise la variable "date", de type std::tm ( cf. https://en.cppreference.com/w/cpp/chrono/c/tm) avec les informations glanées dans les lignes précédentes.

    Les lignes 84 à 88, en fonction de la valeur de la variable "d_filename", soit on initialise la variable "date_de_reprise", soit la variable "date_de_sortie". (C'est complètement bancal comme approche.)
    Compliqué pour moi !!!

    Google : Aphasie ===> "date c++" ===> page 1...10 : pas trouvé !!!

    Le calendrier grégorien : Ah oui, c'est vrai !!!

    Je sais mais j'ai oublié suite à mon AVC, du coup c'est compliqué pour moi.

    Je n'a marre

  6. #286
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 139
    Points : 12 239
    Points
    12 239
    Par défaut
    Je n'a marre
    Courage, vous progressez.
    Vous utilisez des exceptions, peut-être de manière trop "exaltées" mais vous avez creusé de vous même la notion de type d'exception, etc...
    C'est des choses qui vous seront utiles.
    Faut juste essayer de les utiliser à bon escient.

    Vous isolez des fonctionnalités dans des fonctions, c'est bien.(BIS)

    Google : Aphasie ===> "date c++" ===> page 1...10 : pas trouvé !!!
    Remarquez que j'ai posé une question bien plus précise :
    how to verify date in C++
    Mais c'est pas grave, le résultat de la recherche : la fonction "checkdate" fait le taf.
    Vous devriez, au moins provisoirement, l'intégrer à votre code.

    Ainsi, votre code sera bien plus simple en l'utilisant.

    du coup c'est compliqué pour moi.
    Mais le code que vous nous présentez est très complexe aussi.

    Moi, je pense qu'on devrait voir le code de "checkdate" ou de "Cinema: ParseDate" qui sont bien plus simple et concis, non ?

    Sinon, on peut toujours regarder les fonctions que vous postez mais elles sont trop longues.
    Peut-être commencer par l'une des lignes de ces fonctions qui vous semble compliquée ou obscure ?

  7. #287
    Membre expérimenté
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    614
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 614
    Points : 1 369
    Points
    1 369
    Par défaut
    Salut,

    La sérialisation/désérialisation c'est le noeud de votre problème, en l'ignorant vous n’avancez pas, c'est du vagabondage.
    YAML ou JSON c'est comme une base de données. Interroger une base de données c'est infiniment plus simple que de parser des textes qui ne sont même pas structurés de la même manière. Pour le reste, la Lib standard a tout ce qu'il faut, y compris pour les dates. En plus, une date correctement formée n'est pas forcément valide, et ça, c'est pris en compte dans la Lib. Ce qui n'est pas dans la Lib est peut-être dans Boost, etc. Bref, voir autant d'énergie dépensée pour que ça se termine sur un épuisement, ça me fait de la peine.

    Mon précédent message a déjà 4 mois. L'on ne dirait pas, hein ?

    Citation Envoyé par kaitlyn Voir le message
    À continuer comme ça à vous battre avec la console windows, le principal intéressé n'apprendra rien et l'année prochaine il en sera toujours au même point.
    ...
    Nowide (la déclinaison autonome de boost.nowide), c'est la partie windows i/o en utf-8.
    ...
    yaml-cpp, moteur pour la sérialisation/désérialisation de données au format YAML.
    ...
    ça le mettra sur les rails et il pourra enfin commencer à réapprendre le C++ et sa bibliothèque.

  8. #288
    Nouveau Candidat au Club Avatar de Laurent_B_
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2021
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 512
    Points : 0
    Points
    0
    Par défaut
    Bonjour,

    Pouvez-vous réduire les paragraphes et petit à petit (ma sœur) !

    Date ! Ok !

    Merci beaucoup

  9. #289
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 139
    Points : 12 239
    Points
    12 239
    Par défaut
    Ok.

    Mais quel est votre orientation ?

    - comprendre le vieux code compliqué
    - apprendre à structurer le code pour qu'il reste simple et facile à faire évoluer
    - autre ?

    La gestion des dates, c'est bon pour vous, ou c'est le sujet sur lequel vous voulez "creuser" ?

  10. #290
    Nouveau Candidat au Club Avatar de Laurent_B_
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2021
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 512
    Points : 0
    Points
    0
    Par défaut
    Les dates ?

    Merci d'avance

  11. #291
    Membre expérimenté
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    614
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 614
    Points : 1 369
    Points
    1 369
    Par défaut
    Salut,

    Mon précédent message s'adressait essentiellement à bacelar, désolée.

    @bacelar.
    La lib date (Calendar et timezone) n'est pas encore totalement disponible dans les versions "releases" des principaux compilateurs.
    L’implémentation de base est ci-dessous avec toute sa documentation, plus des présentations vidéos. Elle fonctionne très bien dès C++11.
    https://howardhinnant.github.io/
    https://howardhinnant.github.io/date/date.html
    https://howardhinnant.github.io/date/tz.html

    Merci à Howard Hinnant pour ce formidable travail.

    EDIT:

    Summary

    This is actually several separate C++11/C++14/C++17 libraries:

    1. `"date.h"` is a header-only library which builds upon `<chrono>`. It adds some new `duration` types, and new `time_point` types. It also adds "field" types such as `year_month_day` which is a struct `{year, month, day}`. And it provides convenient means to convert between the "field" types and the `time_point` types.

    * Documentation: http://howardhinnant.github.io/date/date.html
    * Video: https://www.youtube.com/watch?v=tzyGjOm8AKo
    * Slides: http://schd.ws/hosted_files/cppcon20...nant_dates.pdf

    1. `"tz.h"` / `"tz.cpp"` are a timezone library built on top of the `"date.h"` library. This timezone library is a complete parser of the IANA timezone database. It provides for an easy way to access all of the data in this database, using the types from `"date.h"` and `<chrono>`. The IANA database also includes data on leap seconds, and this library provides utilities to compute with that information as well.

    * Documentation: http://howardhinnant.github.io/date/tz.html
    * Video: https://www.youtube.com/watch?v=Vwd3pduVGKY
    * Slides: http://schd.ws/hosted_files/cppcon20...Con%202016.pdf

  12. #292
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 139
    Points : 12 239
    Points
    12 239
    Par défaut
    Merci @kaitlyn pour toutes ces infos.

    On va essayer de faire en sorte que @Laurent_B_ s'en serve.

    @Laurent_B_, je ne connais pas la "librairie" que mentionne @kaitlyn, mais avec quelques bonnes bases en C++ et des librairies bien foutues, c'est très facile de pouvoir s'en servir rapidement et efficacement.

    Franchement, la gestion des dates et des heures, c'est des trucs les plus complexes des machins basiques/standard en programmation.
    C'est tellement le bordel que même 25 ans après la première normalisation du C++, la librairie standard du C++ ne gèrent pas forcement tous les cas correctement.
    (Et c'est la même chose dans les autres langages)

    Les dates utilisées en Occident se basent sur le calendrier instauré par le pape Grégoire "je sais plus combien", dans les années 1582.
    Pour avoir une vue historique de tout ce bordel, AstronoGeek en a fait une vidéo plutôt complète :


    Cela explique pourquoi la librairie standard a (eu) du mal à proposer un truc solide.

    Mais dans votre cas d'usage (Occident seulement et dates récentes), vous pouvez utiliser des "bricolages" comme la la fonction "checkdate" qu'on a trouvé sur le net.
    En utilisant la librairie proposée par @kaitlyn, on aurait moins de restrictions sur la nature des dates.

    Votre code semble avoir choisi le type "std::tm" (https://en.cppreference.com/w/cpp/chrono/c/tm) pour stocker 2 dates, la "date de sortie" et la "date de reprise", ce qui est assez logique.

    Mais la problématique que semble vouloir résoudre les extraits de code que vous nous présentez, c'est de remplir/initialiser ces dates à partir du contenu de fichiers contenant des chaines de caractères au format ASCII ou UNICODE (c'est pas clair), formatés selon un schéma de la forme :
    - 4 chiffres pour l'année dans le calendrier grégorien
    - un séparateur : soit "/", soit "-", soit ".", soit encore " "
    - 2 chiffres pour le numéro du mois (entre 1 et 12) dans le calendrier grégorien
    - un séparateur
    - 2 chiffres pour le numéro du jour (entre 1 et 31) dans le calendrier grégorien

    Comme toujours en informatique, il faut toujours séparer les actions complexes en sous-actions plus simples.

    Ici, la seule sous-action spécifique à ces initialisations, c'est de convertir une chaîne de caractère en une date sous forme d'un "std::tm". (les autres sous-actions : - la lecture du contenu d'un fichier a déjà été codé dans une autre fonction pas besoin de le refaire ; -l'affectation à un champ spécifique est simple et spécifique au constructeur de l'objet Cinema (Film c'est mieux comme nom de classe, non?) donc pas besoin de faire un truc à part)

    C'est ce que fait la fonction "Cinema:: ParseDate" qui prend en paramètre une "std::wstring" (une chaîne de caractères) et retourne un std::tm.
    Ainsi, cette fonction sera utilisable potentiellement dans plain d'autres cas d'utilisation.

    Pour l'implémentation du découpage de la chaîne de caractère en 3, je me base sur un outil informatique très puissant : "les expressions régulières".

    En utilisant cette expression régulière, le code est plus concis, plus direct, et plus simple, si on connait les expressions régulières.

    Si vous ne voulez pas utiliser les expressions régulières, c'est dommage, mais on peut vous donner une version sans les expressions régulières (donc moins concise) mais qui ne cache pas le sens du travail effectué, contrairement à la fonction "Cinema:: afficher_Date_de_reprise_ou_de_sortie"

  13. #293
    Nouveau Candidat au Club Avatar de Laurent_B_
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2021
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 512
    Points : 0
    Points
    0
    Par défaut
    Bonjour,

    Les dates utilisées en Occident se basent sur le calendrier instauré par le pape Grégoire "je sais plus combien", dans les années 1582.
    Pour avoir une vue historique de tout ce bordel, AstronoGeek en a fait une vidéo plutôt complète :


    Cela explique pourquoi la librairie standard a (eu) du mal à proposer un truc solide.

    Mais dans votre cas d'usage (Occident seulement et dates récentes), vous pouvez utiliser des "bricolages" comme la la fonction "checkdate" qu'on a trouvé sur le net.
    En utilisant la librairie proposée par @kaitlyn, on aurait moins de restrictions sur la nature des dates.
    Oh ! Oui, c'est vrai ! Merci

  14. #294
    Membre expérimenté
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    614
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 614
    Points : 1 369
    Points
    1 369
    Par défaut
    Salut,

    Je vous ai fait un exemple complet et abordable :

    P.S.: @bacelar, disclaimer: le code a été compilé et testé avec une version spéciale de la lib date, c'est ce que j'avais d’immédiatement à portée. Il n'y a aucune chance que, pour ce code, ça pose problème mais sache le quand même.

    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
    #include <iostream>
    #include <sstream>
    #include <date/date.h> //lib date https://github.com/HowardHinnant/date/releases
    //Other examples at https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes
     
     
    void test_fr_date_detailed(const std::string& input)
    {
        const std::string date_format{"%d/%m/%Y"};
        std::istringstream iss{input};
        date::year_month_day ymd;
        iss>> date::parse(date_format, ymd); //https://en.cppreference.com/w/cpp/chrono/year_month_day/from_stream
        if ( ! iss) //or if (iss.fail()) or if ( ! ymd.ok()) // <=> if parsing failed then ...
            std::cout<< input<< " : invalid format or invalid date!\n";
        else
            std::cout<< input<< "   <==> "<< ymd<< " : ok\n";
    }
     
     
    void test_fr_date_compact(const std::string& input)
    {
        date::year_month_day ymd;
        std::istringstream iss{input};
        if (date::from_stream(iss, "%d/%m/%Y", ymd).fail()) // or if ( ! date::from_stream(iss, "%d/%m/%Y", ymd))
            std::cout<< input<< " : invalid format or invalid date!\n";
        else
            std::cout<< input<< "   <==> "<< ymd<< " : ok\n";
    }
     
     
    int main()
    {
        test_fr_date_detailed("29/02/2023");
        test_fr_date_detailed("29/02/2020");
        test_fr_date_detailed("2023/03/03");
        test_fr_date_detailed("03/03/2023");
        std::cout<< "============================================\n";
        test_fr_date_compact("29/02/2023");
        test_fr_date_compact("29/02/2020");
        test_fr_date_compact("2023/03/03");
        test_fr_date_compact("03/03/2023");
    }
    Citation Envoyé par Output
    29/02/2023 : invalid format or invalid date!
    29/02/2020 <==> 2020-02-29 : ok
    2023/03/03 : invalid format or invalid date!
    03/03/2023 <==> 2023-03-03 : ok
    ============================================
    29/02/2023 : invalid format or invalid date!
    29/02/2020 <==> 2020-02-29 : ok
    2023/03/03 : invalid format or invalid date!
    03/03/2023 <==> 2023-03-03 : ok

  15. #295
    Nouveau Candidat au Club Avatar de Laurent_B_
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2021
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 512
    Points : 0
    Points
    0
    Par défaut
    Bonjour,

    Oui, je sais ! Plus tard !

    À cause : https://www.b-lolo.fr/ : WordPress (ici), Matomo (ici), … Compliqué tout ça !!!

    Merci d'avance

  16. #296
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 139
    Points : 12 239
    Points
    12 239
    Par défaut
    De nouveau prêt à en découdre avec le code ?

    Pas de question précise ?

    Avez-vous à jour les sources dans votre Github ?

    Happy Programming !!!

  17. #297
    Nouveau Candidat au Club Avatar de Laurent_B_
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2021
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 512
    Points : 0
    Points
    0

  18. #298
    Nouveau Candidat au Club Avatar de Laurent_B_
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2021
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 512
    Points : 0
    Points
    0
    Par défaut
    J'ai oublié : https://github.com/laurentbouleau/You !!!
    Mince !

  19. #299
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 139
    Points : 12 239
    Points
    12 239
    Par défaut
    https://github.com/laurentbouleau/You
    Il semble vide.

    ttps://github.com/laurentbouleau/You-1
    Plus vieux (7 mois au lieu de 6 mois).

    Pouvez-vous compiler et exécuter le résultat de compilation de ce projet Visual Studio ?

    Si oui, quel changement voulez-vous apporter, quel dysfonctionnement voulez-vous corriger, est-ce des bouts de votre code que vous cherchez à redompter ?

  20. #300
    Nouveau Candidat au Club Avatar de Laurent_B_
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2021
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 512
    Points : 0
    Points
    0
    Par défaut
    Bonsoir,

    J'ai oublié Mince !!!

    Simple, mais... Bon
    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    const int Cinema::afficher_Date_1(std::wstring& d, std::wstring const& nomFichier)
    {
    #if Cinema_afficher_Date_1_ == 1
    	//wcout << B_T << L"const int Cinema::afficher_Date_1(" << d << L", " << nomFichier << L") :" << B_t << endl;
    #endif
    	if (d == L"")
    	{
    #if Cinema_afficher_Date_1_ == 1
    		std::wcerr << L"    " << L"date=[???]" << std::endl;
    		E.afficher_X(-1, nomFichier, L"Date=[???] erreur !!!");
    #endif
    		return -1;
    	}
    	std::size_t pos;
    	pos = d.length();
    	d = d.substr(0, pos - 4);
     
    	if (d[1] == L'h' && d[5] == L'm' && d[6] == L'i' && d[7] == L'n')
    	{
    		int i = ::afficher_Temps(d, temps);
    		if (i == -1)
    			return -1;
    		return i;
    	}
     
    	if (pos < 10)
    	{
    #if Cinema_afficher_Date_1_ == 1
    		std::wcerr << L"    " << L"Date={" << d << L"} erreur !!!" << std::endl;
    #endif
    		E.afficher_X(-1, nomFichier, L"Date={" + d + L"} erreur !!!");
    		return -1;
    	}
    	int year[_X_] = { 0 }, month[_X_] = { 0 }, day[_X_] = { 0 };
    	std::wstring d2 = L"";
    	int w = 0;
    	int i = 0, j = 0, k = 0;
    	int J = 0;
    	//int I = D_I;
    #if Cinema_afficher_Date_1_ == 1
    	std::wcout << L"    " << L"Date=[" << d << L"]" << std::endl;
    #endif
    	int Y = 0, M = 0, D = 0;
    	bool vrai_year = false;
    	bool vrai_month = false;
    	bool vrai_day = false;
    	while (
    		d[0] != std::wstring::npos &&
    		!(d[0] == L'_' && (pos = d.length()) == 1) &&
    		!(d[0] == L'_' && d[1] == L' ' && (pos = d.length()) > 2) &&
    		!(d[0] == L' ')
    		)
    	{
    		std::wcout << L">>> Y=" << Y << std::endl;
    		std::wcout << L">>> M=" << M << std::endl;
    		std::wcout << L">>> D=" << D << std::endl;
    		system("PAUSE");
    		// day[k]
    		if (!vrai_day &&
    			d[0] == L'_' &&
    			ParseDay(M, D = std::stoi(d.substr(1, 2)), Y)
    			)
    		{
    			std::wcout << L"D : Y=" << Y << L", M=" << M << L", D=" << D << std::endl;
    			k++;
    			day[k] = D;
    			d = d.substr(2);
    #if Cinema_afficher_Date_1_ == 1
    			std::wcout << L"    " << L"day[" << k << L"]=" << day[k] << std::endl;
    #endif
    			Date_1[D_I][J].tm_year = year[i] - 1900;
    			Date_1[D_I][J].tm_mon = month[j] - 1;
    			Date_1[D_I][J].tm_mday = day[k];
    			J++;
    			if ((pos = d.length()) == 0)
    				//goto stop;
    			{
    				//goto stop;
    				vrai_day = true;
    				std::wcout << L"ok vrai D[]" << std::endl;
    				break;
    			}
    			//d = d.substr(1);
    			//vrai_day = false;
    			continue;
    		}
     
    		// month[j] + day[k]
    		if (!vrai_month &&
    			d[0] == L'_' &&
    			ParseMonth(M = std::stoi(d.substr(1, 2))) &&
    			d[3] == L'-' &&
    			ParseDay(M, D = std::stoi(d.substr(4, 2)), Y)
    			)
    		{
    			std::wcout << L"MD : Y=" << Y << L", M=" << M << L", D=" << D << std::endl;
    			j++;
    			k = 0;
    			month[j] = M;
    			day[k] = D;
    			d = d.substr(5);
    			Date_1[D_I][J].tm_year = year[i] - 1900;
    			Date_1[D_I][J].tm_mon = month[j] - 1;
    			Date_1[D_I][J].tm_mday = day[k];
    			J++;
    			if ((pos = d.length()) == 0)
    			{
    				//goto stop;
    				vrai_month = true;
    				std::wcout << L"ok vrai D[]" << std::endl;
    				break;
    			}
    			continue;
    		}
     
    		// year[i] + month[j] + day[k]
    		if (!vrai_year &&
    			ParseYear(Y = std::stoi(d.substr(0, 4))) &&
    			(d[4] == L'-') &&
    			ParseMonth(M = std::stoi(d.substr(5, 2))) &&
    			(d[7] == L'-') &&
    			ParseDay(M, D = std::stoi(d.substr(8, 2)), Y)
    			)
    		{
    			std::wcout << L"YMD : Y=" << Y << L", M=" << M << L", D=" << D << std::endl;
    			year[i] = Y;
    			month[j] = M;
    			day[k] = D;
    			//           yyyy-mm-dd
    			d = d.substr(10);
    			Date_1[D_I][J].tm_year = year[i] - 1900;
    			Date_1[D_I][J].tm_mon = month[j] - 1;
    			Date_1[D_I][J].tm_mday = day[k];
    			J++;
    			if ((pos = d.length()) == 0)
    			{
    				//goto stop;
    				vrai_year = true;
    				std::wcout << L"ok vrai" << std::endl;
    				break;
    			}
    			//vrai_year = true;
    			std::wcout << L"---> YMD vrai_year=true continue" << std::endl;
    			continue;
    		}
    		//else
    		//{
    		//	E.afficher_X(i, nomFichier, L"Date erreur (1) !!!");
    		//	return -1;
    		//}
    		// 
    		//std::wcout << L"wwww" << std::endl;
     
    		// '_' et Y
    		if (!vrai_year &&
    			d[0] == L'_' &&
    			ParseYear(Y = std::stoi(d.substr(0, 4)))
    			)
    		{
    			std::wcout << L">>> Y : Y=" << Y << std::endl;
    			i++;
    			j = 0;
    			k = 0;
    			d = d.substr(1);
    #if Cinema_afficher_Date_1_ == 1
    			std::wcout << L"    " << L"Date !!!" << std::endl;
    #endif
    			vrai_year = false;
    			continue;
    		}
    		//else
    		//{
    		//	E.afficher_X(i, nomFichier, L"Date erreur (2) !!!");
    		//	return -1;
    		//}
     
     
    		if (Y != 0 && M != 0 && D != 0 &&
    			(!vrai_year || !vrai_month || !vrai_day))
    		{
    			E.afficher_X(i, nomFichier, L"Date erreur !!!");
    			return -1;
    		}
    		if(Y == 0 || M == 0 || D == 0)
    			break;
    	}
    	//afficher_X(0, _T, L"Cinema::afficher_Date_1() !!!");
    	// Ok !
    //stop:
    	if (d[0] == L'_')
    	{
    		D_1_[D_I] = true;
    		d = d.substr(1);
    	}
    	if (d[0] == L' ')
    	{
    		d = d.substr(1);
    		Date_1_t[D_I] = d;
    	}
    	wchar_t date_string[15];
    	D_J[D_I] = J - 1;
    #if Cinema_afficher_Date_1_ == 1
    	std::wcout << L"    " << L'(';
    	for (i = 0; i < J; i++)
    	{
    		wcsftime(date_string, 15, L"%d/%m/%Y", &Date_1[D_I][i]);
    		std::wcout << date_string;
    		if (i < J - 1)
    			std::wcout << L", ";
    	}
    	if (D_1_[D_I] == true)
    		std::wcout << L"(_)";
    	if (w == 1)
    		std::wcout << L' ' << Date_1_t[D_I];
    	std::wcout << L')' << std::endl;
    #else
    	for (i = 0; i < J; i++)
    		wcsftime(date_string, 15, L"%d/%m/%Y", &Date_1[D_I][i]);
    #endif
    #if Cinema_afficher_Date_1_ == 1
    	std::wcout << L"    " << L"D_J[" << D_I << L"]=[" << J - 1 << L"]" << std::endl;
    #endif
    	D_I++;
    #if Cinema_afficher_Date_1_ == 1
    #endif
    	std::wcout << L"OK OK OK" << std::endl;
    	return EXIT_SUCCESS;
    }
    2022-05-19_20 Netflix.txt (pas-à-pas)
    2022-08-01_01_01_05_05_08.txt (pas-à-pas)
    2022-08-20_ Netflix.txt (petit à petit)
    2023-09-04.txt (pas-à-pas)
    ...
    J'aimerai beaucoup toi/vous ?
    Merci vraiment

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Probléme avc la formclosing
    Par dv-2008 dans le forum VB.NET
    Réponses: 2
    Dernier message: 23/03/2008, 16h33
  2. probléme avc console.readline()
    Par dv-2008 dans le forum VB.NET
    Réponses: 7
    Dernier message: 10/03/2008, 00h33
  3. j'ai un probléme avc un code vb.net aider moi svp
    Par dv-2008 dans le forum VB.NET
    Réponses: 12
    Dernier message: 29/01/2008, 09h20
  4. Problème avc une requête
    Par Raiga dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 30/06/2007, 18h36
  5. Toujours problème de lien avce la lib Cblas
    Par Kirou dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 19/06/2007, 14h50

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