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. #501
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 507
    Par défaut
    Il y a pas mal de chose qui "clochent" dans votre code actuellement.

    Premièrement, n'utilisez pas de "using namespace" ou des alias de namespace dans les .h, à n'utiliser que dans les .cpp.

    Secondement, votre code ne fait pas vraiment ce qu'il est censé faire quand on le lit. (Il est piégeux)
    Pour ne pas se faire tromper par son code, il faut vérifier ce qu'il fait vraiment en utilisant le mode pas à pas du débugueur.
    Si vous ne maitrisez pas ce type d'usage du débugueur, investissez un peu de temps pour vous en servir efficacement.

    P.S.: Quelle est la question dans votre message de "12/02/2024, 21h30" ?
    Ah ! Super ou pas
    Bin, pas super, pour le coup, et cela illustre assez bien le "secondement", votre code piégeux.

    Déjà, faire 2 fois la même boucle "for (const auto& entry_saison : fs::directory_iterator(entry_serie))", ça sent pas bon.
    Si le code tient un minimum la route, on devrait tout faire dans une seule boucle.
    Puis "saison.~saison();", ON N'APPELE JAMAIS EXPLICITEMENT LE DESTRUCTEUR !!!!
    Une très grosse partie du code sont des "std::wcout <<" qui n'ont aucune raison d'exister (utilisez le débugueur pour valider votre programme, pas faire des "print coucou" toute les 2 lignes).
    Il y a tellement de "std::wcout <<" que ça cache le sens du code, je trouve.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (entry_serie.is_regular_file())
            {
                std::wcout << L"===> is_regular_file(1)=[" << entry_serie << L']' << std::endl;
                std::wcout << std::endl;
                continue;
            }
    Bout de code qui ne sert à rien, sauf cacher le fonctionnement nominal du code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Saison saison;
    auto const& nomDossier = entry_serie.path().filename();
    saison.afficher_Dossier(nomDossier);
    C'est dans ce type de code que les pièges sont le plus présent.
    Vous avez beaucoup de code qui ne servent qu'à vous piéger.

    Un code bien plus "correct" aurait été :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Saison saison;
    saison.afficher_Dossier(entry_serie);
    Le premier paramètre de "afficher_Dossier" est un chemin (fs::path) et non une std::string ; car on doit pouvoir afficher un répertoire qui est contenu dans un autre répertoire, par exemple.
    Mais le code de "afficher_Dossier" ne gère pas le fait que le répertoire peut être contenu dans un autre répertoire.
    En utilisant "correctement" la fonction "afficher_Dossier", on détecte le problème, à régler dans "afficher_Dossier" et pas dans le code l'appelant.
    Vous devez revoir le code d'"afficher_Dossier" pour qu'il gère correctement le fait que le répertoire peut être dans un autre répertoire (le code en sera encore plus simple qu'actuellement, surtout sans ces foutu "std::wcout <<" inutils).

    Comme actuellement vous ne faites rien de spécifique à un dossier, mais juste faire du décodage de nom qui n'a rien de spécifique à un dossier, en utilisant mal la fonction (en lui passant le nom du répertoire à la place du chemin vers ce répertoire) vous ne tombez pas sur le problème.
    2 bugs qui se cachent l'un l'autre.
    Mais dès que vous voudrez implémenter correctement "Saison::afficher_Dossier", donc en accédant au répertoire et pas juste faire mumuse avec son nom, les 2 bugs ne pourront plus se cacher l'au l'autre.

    Dans ce genre de cas de "double bugs", corrigez l'appel de la fonction, puis fait en sorte que la fonction appelée fasse correctement son job.

    Quand on prend les sources depuis Git, qu'on compile, et qu'on lance l'exécutable via le débogueur, ça plante en ligne 457 d'Exemple.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    saison.afficher_Fichier(entry_saison);
    Mais exactement comme pour "Saison::afficher_Dossier", le problème n'est pas dans le code appelant la fonction, qui ici est correct, mais dans la fonction elle-même.
    Elle a les mêmes défaut que "Saison::afficher_Dossier", elle ne gère pas le fait qu'un fichier puissent être dans un répertoire.
    Considérez bien qu'on passe en paramètre de ces fonctions un chemin et NON un nom de fichier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    if (entry_saison.is_regular_file() && saison.episode == 0) 
                    {
                        saison.afficher_Episodes(entry_saison);
                        saison.episode = 1;
                        std::wcout << L"Episodes ok !!!" << std::endl;
                        //system("PAUSE");
                        std::wcout << std::endl;
                        break;
                    }
                    if (saison.episode == 0)
                    {
                        std::wcout << L"Pas d'episodes !!!" << std::endl;
                        exit(1);
                    }
    Ce code n'a aucun sens ou il est très maladroit.

    Après, c'est la conception de la classe "Saison" qui fait que ce code est complexe et vraisemblablement faux.
    Là, vous gérez "à la main" un champ de "saison" : episode qui n'est ni très logique ni très facile à comprendre.
    Une saison, elle contient des episodes, mais pourquoi alors le champ "episodes" est une "std::pair<unsigned short int, std::wstring>" et pas un simple "std::vector<std::wstring>", ou encore mieux un "std::vector<Episode>" (avec une classe Episode à concevoir) ???
    Si le champ "episodes" était un "std::vector", par exemple, pour avoir le nombre d'épisodes d'une saison, un simple "saison.episodes.size()" suffirait et aucun manipulation à base "saison.episode = xx;" ne serait nécessaire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void Saison::afficher_Fichier(fs::path const& nomFichier)
    {...}
    Comme déjà indiqué ci-avant, vous confondez chemin d'un fichier/répertoire et son "nom".

    Si vous appelez correctement ces fonctions "void Saison::afficher_xxx", une petite modification comme celle-ci pourrait régler beaucoup de problèmes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void Saison::afficher_ccc(fs::path const& cheminFichier)
    {
        auto nomFichier = cheminFichier.filename();
    ...
    }
    Mais bon, le reste du code de la fonction me semble bancal, avec l'utilisation de "find_last_of" et autres bidules à la "substr" qui n'ont plus rien à faire ici.
    Simplifiez votre code rapidement, SVP !!!

    Marche pas !!!
    ...
    Sans L"10.txt" !!! (saison.afficher_Episodes(entry_saison); )
    Problème !!! Solution ?
    C'est "normal", la "logique" du code est complètement "pété".
    Comme indiqué plus haut, utilisez un type "correct" pour le champ "episodes" de la classe Saison et vous n'aurez pas à faire du code "complexe".

    J'ai l'impression que l'utilité des classes vous échappe un peu, non ?
    Elles sont là pour simplifier le codage.

  2. #502
    Membre éclairé Avatar de Laurent_B_
    Homme Profil pro
    Ingénieur de déploiement réseaux
    Inscrit en
    Avril 2021
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur de déploiement réseaux
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 786
    Par défaut
    Il y a pas mal de chose qui "clochent" dans votre code actuellement.

    Premièrement, n'utilisez pas de "using namespace" ou des alias de namespace dans les .h, à n'utiliser que dans les .cpp.
    Ok !

    Après, rien compris !!!

    Pas-à-pas !!! (l'exaspération !!!)

    Ok ! J'ai peur : Alors, pas-à-pas !!!

  3. #503
    Membre éclairé Avatar de Laurent_B_
    Homme Profil pro
    Ingénieur de déploiement réseaux
    Inscrit en
    Avril 2021
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur de déploiement réseaux
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 786
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void Saison::afficher_Dossier(fs::path const& cheminFichier)
    {
        std::wcout << L"cheminFichier=[" << cheminFichier << L']' << std::endl;
        auto nomFichier = cheminFichier.filename();
        std::wcout << L"nomFichier=[" << nomFichier << L']' << std::endl;
    
        //assert(nomFichier > 0 && L"Nom de dossier vide");
        //std::size_t pos = 0;
        std::wstring wstr = ??? // nomFichier
    ...
    Merci

  4. #504
    Membre éclairé Avatar de Laurent_B_
    Homme Profil pro
    Ingénieur de déploiement réseaux
    Inscrit en
    Avril 2021
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur de déploiement réseaux
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 786
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        std::wstring wstr = nomFichier.filename().wstring();
    Oui ou non ?

    Merci

  5. #505
    Membre éclairé Avatar de Laurent_B_
    Homme Profil pro
    Ingénieur de déploiement réseaux
    Inscrit en
    Avril 2021
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur de déploiement réseaux
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 786
    Par défaut
    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
    void Saison::afficher_Dossier(fs::path const& cheminFichier)
    {
        std::wcout << L"cheminFichier=[" << cheminFichier << L']' << std::endl;
        auto nomFichier = cheminFichier.filename();
        std::wcout << L"nomFichier=[" << nomFichier << L']' << std::endl;
     
        //assert(nomFichier > 0 && L"Nom de dossier vide");
        std::size_t pos = 0;
        //std::wstring wstr = nomFichier.wstring();
        auto wstr = nomFichier.filename().wstring();
        assert(wstr.length() > 9 && L"Nom de fichier trop court pour avoir au moins une date");
        wstr = wstr.substr(pos);
     
        wchar_t sp = L' ', tiret = L'-';
        //int y;
        auto y = std::stoi(wstr, &pos);
        assert(1582 <= y && L"L'année aaaaa");
        wstr = wstr.substr(4);
        try
        {
            test_date_tire(wstr[0]);
        }
        catch (exception_date_tiret e2)
        {
            std::wcout << L"Exception a été capturée : " << e2.get_message() << std::endl;
            exit(1);
        }
        wstr = wstr.substr(1);
        auto m = std::stoi(wstr, &pos);
        assert((1 <= m && m <= 12) && L"Le mois aaaaa");
        wstr = wstr.substr(2);
        try
        {
            test_date_tire(wstr[0]);
        }
        catch (exception_date_tiret e2)
        {
            std::wcout << L"Exception a été capturée : " << e2.get_message() << std::endl;
            exit(1);
        }
        wstr = wstr.substr(1);
        auto d = std::stoi(wstr, &pos);
        assert((1 <= d && d <= 31) && L"Le jour aaaaa");
        if (!checkday(m, d, y))
        {
            std::wcout << L"Le jour aaaa !!!" << std::endl;
            exit(1);
        }
        std::tm tm;
        tm.tm_year = y - 1900;
        tm.tm_mon = m - 1;
        tm.tm_mday = d;
        wstr = wstr.substr(2);
        dossier.first = tm;
        dossier.second = wstr;
        std::wcout << L"dossier.first ok !!!" << std::endl;
        std::wcout << L"dossier.second=[" << dossier.second << L']' << L" ok !!!" << std::endl;
        std::wcout << L"Dossier(1)=[" << wstr << L']' << std::endl;
    }
    Ok ou non ?

    Et Windows Studio ---> Déboguer ---> ???

    Merci vraiment

  6. #506
    Membre éclairé Avatar de Laurent_B_
    Homme Profil pro
    Ingénieur de déploiement réseaux
    Inscrit en
    Avril 2021
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur de déploiement réseaux
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 786
    Par défaut
    Bonjour bacelar,

    Et Windows Studio ---> Déboguer : Ou qu'il est ? Expliqué-moi ?

    Moi : simple et pas-à-pas !
    Vous : Compliqué et longues textes !

    Moi, je suis fatigué ! Et l'anglais : https://en.cppreference.com/w/cpp/filesystem/path et Windows Paramètres ---> Option d'ergonomie ---> Narrateur : pas facile !!!

    Merci beaucoup

  7. #507
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 507
    Par défaut
    Pouvez-vous indiquer ce que vous ne comprenez pas ?
    Sinon ça n'avancera pas, car on ne connait pas précisément vos difficultés.

    Il y a des choses concrètes dans mon précédent message que je ne reprendrais pas.

    Il faut que vous compreniez la différence entre un chemin et un nom de fichier.
    "2015-02-09" est un nom de fichier/répertoire.
    "./Better Call Saul.[2015-2022]\2015-02-09" est le chemin vers le même fichier/répertoire.



    Ok, on va faire plus directif.

    Dans le fichier "Exemple.h":
    Supprimer les ligne 31 et 32.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    using namespace std;
    namespace fs = std::filesystem;
    On ne devrait jamais mettre ce type de ligne dans un .h.
    Ca change rien pour l'instant, mais c'est un pratique dangereuse.
    Avoir toujours de "bonnes" habitude.

    Dans "exemple.cpp", il faut supprimer la ligne suivante (ligne 477) :
    Dans "Exemple.cpp", il y a du code comme celui des lignes 431 à 433:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Saison saison;
    auto const& nomDossier = entry_serie.path().filename();
    saison.afficher_Dossier(nomDossier);
    Ici, vous ne transmettez à "afficher_Dossier" que le nom du fichier et pas le chemin complet vers le fichier, c'est une "grosse erreur".
    Il faut donc remplacer ces 3 lignes par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Saison saison;
    saison.afficher_Dossier(entry_serie);

    Dans "serie.h", changer le nom des paramètres des fonctions de la classe Saison :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        void afficher_Avec(fs::path const& cheminFichier);
        void afficher_Dossier(fs::path const& cheminDossier);
        void afficher_Fichier(fs::path const& cheminFichier);
        void afficher_Date_ou_Dates(fs::path const& cheminFichier);
        void afficher_Date_ou_Dates_Titres(fs::path const& cheminFichier);
        void afficher_Episodes(fs::path const& cheminFichier);
        void afficher_Note(fs::path const& cheminFichier);
    C'est "cosmétique, mais c'est important que les noms correspondent à ce qu'ils représentent.

    Dans "serie.cpp", faire les mêmes changement que dans le .h.
    Par exemple, ligne 136:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void Saison::afficher_Dossier(fs::path const& cheminDossier)
    Changer le code de la fonction (en attendant de le simplifié) en ajoutant une ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Saison::afficher_Dossier(fs::path const& cheminDossier)
    {
        auto nomDossier = cheminDossier.filename().wstring();
        ....
    Juste cette ligne ajoutée au début de la fonction permet de maintenir la "compatibilité" du code de la fonction avec le nouveau type du paramètre.
    Cette action de renommage et d'ajout de ligne est à faire dans les 6 autres fonctions de la classe "Serie".

    Comme "nomDossier" est de nouveau une std::wstring, vous n'avez plus a vous encombrez de variables supplémentaires comme "nd", et en supprimant les try/catch qui n'ont rien à faire ici (le exit est une idée originale, mais contre-productive) et en lançant "correctement" les exceptions :
    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
    void Saison::afficher_Dossier(fs::path const& cheminDossier)
    {
        auto nomDossier = cheminDossier.filename().wstring();
        std::wcout << L"Dossier=[" << nomDossier << L']' << std::endl;
        assert(nomDossier.length() > 0 && L"Nom de dossier vide");
        std::size_t pos = 0;
        std::wstring wstr = nomDossier.substr(pos);
        assert(nomDossier.length() > 9 && L"Nom de fichier trop court pour avoir au moins une date");
     
        wchar_t sp = L' ', tiret = L'-';
        auto y = std::stoi(wstr, &pos);
        assert(1582 <= y && L"L'année aaaaa");
        wstr = wstr.substr(4);
        test_date_tire(wstr[0]);
        wstr = wstr.substr(1);
        auto m = std::stoi(wstr, &pos);
        assert((1 <= m && m <= 12) && L"Le mois aaaaa");
        wstr = wstr.substr(2);
        test_date_tire(wstr[0]);
        wstr = wstr.substr(1);
        auto d = std::stoi(wstr, &pos);
        assert((1 <= d && d <= 31) && L"Le jour aaaaa");
        if (!checkday(m, d, y))
        {
            throw std::invalid_argument(cheminDossier.string() + " n'a pas un nom corresondant à une date valide.");
        }
        std::tm tm;
        tm.tm_year = y - 1900;
        tm.tm_mon = m - 1;
        tm.tm_mday = d;
        wstr = wstr.substr(2);
        dossier.first = tm;
        dossier.second = wstr;
        std::wcout << L"dossier.first ok !!!" << std::endl;
        std::wcout << L"dossier.second=[" << dossier.second << L']' << L" ok !!!" << std::endl;
        std::wcout << L"Dossier(1)=[" << nomDossier << L']' << std::endl;
    }
    La fonction "test_date_tire" devrait retournée un bool et ne pas lancer d'exceptions "intempestives".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bool test_date_tire(wchar_t d)
    {
        return (d == L'-');
    }
    (corriger aussi la signature dans le .h)
    Ce qui permet d'avoir des exceptions plus "utiles" :
    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
    void Saison::afficher_Dossier(fs::path const& cheminDossier)
    {
        auto nomDossier = cheminDossier.filename().wstring();
        std::wcout << L"Dossier=[" << nomDossier << L']' << std::endl;
        assert(nomDossier.length() > 0 && L"Nom de dossier vide");
        std::size_t pos = 0;
        std::wstring wstr = nomDossier.substr(pos);
        assert(nomDossier.length() > 9 && L"Nom de fichier trop court pour avoir au moins une date");
    
        wchar_t sp = L' ', tiret = L'-';
        //int y;
        auto y = std::stoi(wstr, &pos);
        assert(1582 <= y && L"L'année aaaaa");
        wstr = wstr.substr(4);
    
        if (!test_date_tire(wstr[0]))
        {
            throw std::invalid_argument(cheminDossier.string() + " : à vous de voir le message qui va bien.");
        }
        wstr = wstr.substr(1);
        auto m = std::stoi(wstr, &pos);
        assert((1 <= m && m <= 12) && L"Le mois aaaaa");
        wstr = wstr.substr(2);
        if (!test_date_tire(wstr[0]))
        {
            throw std::invalid_argument(cheminDossier.string() + " : à vous de voir le message qui va bien aussi ici.");
        }
        wstr = wstr.substr(1);
        auto d = std::stoi(wstr, &pos);
        assert((1 <= d && d <= 31) && L"Le jour aaaaa");
        if (!checkday(m, d, y))
        {
            throw std::invalid_argument(cheminDossier.string() + " n'a pas un nom correspondant à une date valide.");
        }
        std::tm tm;
        tm.tm_year = y - 1900;
        tm.tm_mon = m - 1;
        tm.tm_mday = d;
        wstr = wstr.substr(2);
        dossier.first = tm;
        dossier.second = wstr;
        std::wcout << L"dossier.first ok !!!" << std::endl;
        std::wcout << L"dossier.second=[" << dossier.second << L']' << L" ok !!!" << std::endl;
        std::wcout << L"Dossier(1)=[" << nomDossier << L']' << std::endl;
    }
    Vous devriez faire le ménage des variables et des try/catch et un "bon" usage des exceptions dans les 6 autres fonctions de la classe "Serie".



    Ligne 429 à 454 d'Exemple.cpp, pourquoi 2 boucles au lieu d'une ? :
    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
    for (const auto& entry_saison : fs::directory_iterator(entry_serie))
    {
        auto const& nomFichier = entry_saison.path().filename();
        std::wcout << L"nomFichier=[" << nomFichier << L']' << std::endl;
        if (entry_saison.is_regular_file() && saison.episode == 0) 
        {
            saison.afficher_Episodes(entry_saison);
            saison.episode = 1;
            //system("PAUSE");
            std::wcout << std::endl;
            break;
        }
        if (saison.episode == 0)
        {
            std::wcout << L"Pas d'episode(s) !!!" << std::endl;
            exit(1);
        }
    }
    for (const auto& entry_saison : fs::directory_iterator(entry_serie))
    {
        if (entry_saison.is_regular_file())
        {
            std::wcout << L"===> is_regular_file(2)=[" << entry_saison << L']' << std::endl;
            saison.afficher_Fichier(entry_saison);
        }
    }
    Ne complexifiez pas inutilement le code :

    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
    for (const auto& entry_saison : fs::directory_iterator(entry_serie))
    {
        auto const& nomFichier = entry_saison.path().filename();
        std::wcout << L"nomFichier=[" << nomFichier << L']' << std::endl;
        if (entry_saison.is_regular_file())
        {
            std::wcout << L"===> is_regular_file(2)=[" << entry_saison << L']' << std::endl;
            saison.afficher_Fichier(entry_saison);
            if (saison.episode == 0)
            {
                saison.afficher_Episodes(entry_saison);
                saison.episode = 1;
                //system("PAUSE");
                std::wcout << std::endl;
                break;
            }
        }
        if (saison.episode == 0)
        {
            std::wcout << L"Pas d'episode(s) !!!" << std::endl;
            exit(1);
        }
    }
    Je n'ai plus d'erreur à l'exécution avec la version "Une boucle" mais toujours des erreurs avec la version "2 boucles" => code piégeux et/ou j'ai pas compris le sens de cette deuxième boucle.

    J'ai compris le piège, c'est la présence du break dans la première boucle.
    La première boucle ne sert vraisemblablement qu'à détecter la présence d'un épisode dans une saison, ou pas.
    C'est un code bien trop volumineux pour une si faible fonctionnalité, l'utilisation d'une fonction dédiée à cette fonctionnalité est largement justifiée.
    Et en la créant, vous serez rendu rapidement compte que la partie "if (saison.episode == 0)" n'a rien à foutre dans la boucle, car la vérification doit être faites après la boucle.
    Mais il y a un mélange entre l'affichage des épisodes et la détection de la présence d'un épisode dans une saison.
    Ne faites pas 2 choses à la fois dans le code.
    Une version bien plus simple (bon l'exit(1), c'est pas top):
    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
    if (fs::is_directory(entry_serie))
    {
        Saison saison;
        saison.afficher_Dossier(entry_serie);
        for (const auto& entry_saison : fs::directory_iterator(entry_serie))
        {
            auto const& nomFichier = entry_saison.path().filename();
            std::wcout << L"nomFichier=[" << nomFichier << L']' << std::endl;
            if (entry_saison.is_regular_file())
            {
                std::wcout << L"===> is_regular_file(2)=[" << entry_saison << L']' << std::endl;
                saison.afficher_Fichier(entry_saison);
                saison.afficher_Episodes(entry_saison);
                saison.episode = 1;
                //system("PAUSE");
                std::wcout << std::endl;
            }
     
        }
        if (saison.episode == 0)
        {
            std::wcout << L"Pas d'episode(s) !!!" << std::endl;
            exit(1);
        }
    Avec cette version, on voit mieux ce que le code est sensé faire.

    Tout "fonctionne", jusqu'à ce que le fichier dans "entry_saison" est "./Better Call Saul.[2015-2022]\\2015-02-09\\Avec.txt".
    Là, la ligne "episodes.first = std::stoi(wstr, &pos);" dans la fonction "Saison::afficher_Episodes" génère une exception, car "Avec.txt" n'est pas un nombre.
    Pour les autres fichiers avant, leur nom n'étaient pas un nombre ("10.txt","1x01.2024-02-01.txt") mais comme ça commence par un chiffre, "std::stoi" râlait pas trop, mais vous vous retrouvez avec "1x01.2024-02-01.txt", "1x02.2024-02-01.txt", etc... qui porte tous ne même numéro dans "episodes.first" : 1.

    Donc, premièrement, il faudrait avoir un mécanisme qui ne prenne pas "./Better Call Saul.[2015-2022]\\2015-02-09\\Avec.txt" pour un épisode.
    Et en deuxième, faudrait modifier "Saison::afficher_Episodes" pour qu'il fasse correctement son "travail".

    Et les première lignes de "Saison::afficher_Episodes" sont toujours aussi bordélique que beaucoup de fonctions que vous avez écrites, donc pensez à refactorer votre code pour le rendre plus simple;
    Exemple une version de "Saison::afficher_Episodes" toujours boguée mais plus maintenable :
    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
    void Saison::afficher_Episodes(fs::path const& cheminFichier)
    {
        auto nomFichier = cheminFichier.filename().wstring();
        assert(nomFichier.length() > 0 && L"Nom de fichier vide");
     
        std::wcout << L"nf=" << nomFichier << std::endl;
     
        episodes.first = std::stoi(nomFichier);
     
        wstring wstr = lire_fichierTxt(cheminFichier);
        assert((wstr.size() != 0));
     
        episodes.second = wstr;
     
        std::wcout << L"episodes.first=[" << episodes.first << L"], episodes.second=[" << episodes.second << L']' << std::endl;
    }
    (Je ne comprends pas l'intérêt du 2ème assert)
    On voit dans le code un appel à "lire_fichierTxt" qui prend un paramètre une "std::wstring const&" et pas un "std::filesystem::path".
    Ici, ça passe, mais vous devriez revoir toutes vos fonctions pour qu'elles fassent bien la distinction entre un nom de fichier et un chemin vers un fichier. ifstream prend des chemins, pas des noms.

    Pour votre message du "15/02/2024, 22h32"
    Vous avez fourni un code de la forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void Saison::afficher_Dossier(fs::path const& cheminFichier)
    {
        std::wcout << L"cheminFichier=[" << cheminFichier << L']' << std::endl;
        auto nomFichier = cheminFichier.filename();
        std::wcout << L"nomFichier=[" << nomFichier << L']' << std::endl;
     
        //assert(nomFichier > 0 && L"Nom de dossier vide");
        //std::size_t pos = 0;
        std::wstring wstr = ??? // nomFichier
    Vous y êtes presque :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void Saison::afficher_Dossier(fs::path const& cheminDossier)
    {
        auto nomDossier = cheminDossier.filename().wstring();
        std::wcout << L"Dossier=[" << nomDossier << L']' << std::endl;
        assert(nomDossier.length() > 0 && L"Nom de dossier vide");
        std::size_t pos = 0;
        std::wstring wstr = nomDossier;
    En sachant que la variable wstr ne sert à rien ici. (cf. le code complet de la fonction donné plus haut dans ce message.)

    Pour votre message du "15/02/2024, 23h07":
    C'est correct mais évitez de manier trop de variables inutiles et qui font plus d'une chose à la fois (wstr est réutilisée après pour faire autre chose, c'est dangereux, et nommez-les CORRECTEMENT !!!).

    Pour votre message du "15/02/2024, 23h48":
    Non pas OK, KO.
    Le code complet de la fonction est donné plus haut dans ce message. Il est perfectible mais c'est un début. Il est encore simplifiable.
    Et Windows Studio ---> Déboguer ---> ???
    "Windows Studio" ???
    Visual Studio, plutôt, non ?

    Pour utiliser correctement le débogueur de Visual Studio :
    - Sélectionner une ligne où l'on veut que le programme s'interrompe pour qu'on puisse voir les informations qui nous intéressent.
    Nom : debugeurVS1.png
Affichages : 204
Taille : 40,6 Ko
    - Appuyer sur la touche "F9" pour créer un point d'arrêt sur cette ligne, indiqué avec un point rouge dans la merge.
    Nom : debugeurVS2.png
Affichages : 198
Taille : 47,6 Ko
    - Cliquer sur le bouton "Débogueur Windows local" pour lancer le débugueur avec votre programme :
    Nom : debugeurVS3.png
Affichages : 207
Taille : 46,2 Ko

    Le débugueur lance votre programme est le fait s'arrêter au point d'arrêt quand le programme l'atteint.
    Nom : debugeurVS4.png
Affichages : 203
Taille : 136,2 Ko
    La flèche jaune indique où en n'est le programme, ici au niveau du point d'arrêt.
    Vous pouvez voir les valeurs des variables en bas à gauche, dans l'onglet "Automatique"
    Vous pouvez voir la pile d'appel (l'enchainement des appels de fonction) en bas à gauche, dans l'onglet "Pile des appels".
    Vous avez le bouton "Continuer" en haut à gauche pour demander au débugueur de continuer l'exécution du programme jusqu'à ce qu'il atteigne de nouveau un point d'arrêt.
    En haut à droite, il y a 3 boutons qui permettent de débuguer le programme pas-à-pas, à partir du point d'arrêt.
    Celui de gauche permet de rentrer dans le code des fonctions appelées sur la ligne courante.
    Celui du centre permet d'exécuter le programme jusqu'à la ligne suivante, sans entrer dans le code d'une fonction appelée sur la ligne courante.
    Celui de droite permet de faire exécuter le programme jusqu'à revenir dans le code de la fonction appelante.

    C'est la base de l'utilisation d'un débugueur.

    Moi, je suis fatigué ! Et l'anglais : https://en.cppreference.com/w/cpp/filesystem/path et Windows Paramètres ---> Option d'ergonomie ---> Narrateur : pas facile !!!
    Microsoft fournit une version en français de la documentation, mais la qualité de la traduction n'est pas terrible :
    https://learn.microsoft.com/fr-fr/cp...?view=msvc-170
    Commencez par comprendre la différence entre un nom de fichier et un chemin vers un fichier.

  8. #508
    Membre éclairé Avatar de Laurent_B_
    Homme Profil pro
    Ingénieur de déploiement réseaux
    Inscrit en
    Avril 2021
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur de déploiement réseaux
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 786
    Par défaut
    Bonjour bacelar,

    Pouvez-vous indiquer ce que vous ne comprenez pas ?
    ...
    Je n'ai plus d'erreur à l'exécution avec la version "Une boucle" mais toujours des erreurs avec la version "2 boucles" => code piégeux et/ou j'ai pas compris le sens de cette deuxième boucle.
    Ok ! Mais, je suis fatigué !!!

    En plus, Exemple.h/cpp, film_serie.h/cpp et serie.h/cpp : ok !
    Mais, serie.h :
    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
    ...
    class Saison
    {
    public:
        Saison(void);
        ~Saison();
        void afficher_Avec(std::filesystem::path const& cheminFichier);
    ...
        void afficher_Saison(std::filesystem::path const& cheminFichier);
        void afficher_Titre(std::filesystem::path const& cheminFichier);
    private:
        //                               x          t1            t2           t3           temps      p
        std::vector<std::tuple<unsigned int, std::wstring, std::wstring, std::wstring, std::tm, std::wstring>> episode_titres;
        std::vector<std::pair<std::wstring, std::wstring>> avec;
        std::pair<std::tm, std::wstring>dossier; // ???
        std::wstring dos = L""; // ???
        std::vector<std::tuple<unsigned int, std::vector<DateRecord>, std::wstring>>episode;
        std::pair<unsigned short int, std::wstring>saison;
        std::vector<std::wstring> image;
        double note = -1.0;
    };
    
    class Serie
    {
    public:
        Serie(std::filesystem::path racine);
        ~Serie();
        void Print();
        std::vector<Saison>saisons{};
        std::filesystem::path getRacine() { return racine; };
        std::filesystem::path getFileName() { return racine.filename(); };
    private:
        //const bool PrintDate_ou_Dates();
        void PrintEpisode();
        void PrintSaisons();
    
        std::filesystem::path racine;
    
        std::vector<std::wstring>keyColor{ L"\x1b[94;1m", L"\x1b[38;2;0;255;0m" }; // keyColor[0] (bleu) et keyColor[1] (vert)
        std::wstring valuesColor = L"\x1b[38;2;255;255;255m"; // Blanc
    
        //bool affichage;
        bool affichage_Episode_actif = true;
        bool affichage_Saisons_actif = true;
    };
    
    ...
    void Print() et void PrintSaisons() ???
    Problème !!! Pas compris !

    https://github.com/laurentbouleau/Exemple : Février 19

    Ok : (dossier 1 et 2)
    XXXX-YY-ZZ 1
    XXXX-YY-ZZ 2
    1 et 2 ou un autre !!!
    J'ai oublié !
    Alors : std::pair<std::tm, std::wstring>dossier; : ok !

    Mais, plus simple : ok !
    Vous : compliqué !
    Mais : pas-à-pas !!!

    Après, plus tard !!!
    Pour votre message du "15/02/2024, 23h07":
    ...
    Merci beaucoup

  9. #509
    Membre éclairé Avatar de Laurent_B_
    Homme Profil pro
    Ingénieur de déploiement réseaux
    Inscrit en
    Avril 2021
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur de déploiement réseaux
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 786
    Par défaut
    Bonsoir,

    Pour utiliser correctement le débogueur de Visual Studio :
    - Sélectionner une ligne où l'on veut que le programme s'interrompe pour qu'on puisse voir les informations qui nous intéressent.
    ...
    La flèche jaune indique où en n'est le programme, ici au niveau du point d'arrêt.
    Vous pouvez voir les valeurs des variables en bas à gauche, dans l'onglet "Automatique"
    Vous pouvez voir la pile d'appel (l'enchainement des appels de fonction) en bas à gauche, dans l'onglet "Pile des appels".
    Vous avez le bouton "Continuer" en haut à gauche pour demander au débugueur de continuer l'exécution du programme jusqu'à ce qu'il atteigne de nouveau un point d'arrêt.
    En haut à droite, il y a 3 boutons qui permettent de débuguer le programme pas-à-pas, à partir du point d'arrêt.
    Celui de gauche permet de rentrer dans le code des fonctions appelées sur la ligne courante.
    Celui du centre permet d'exécuter le programme jusqu'à la ligne suivante, sans entrer dans le code d'une fonction appelée sur la ligne courante.
    Celui de droite permet de faire exécuter le programme jusqu'à revenir dans le code de la fonction appelante.
    C'est dure !!! Compliqué !!! Mais, bon... ok !

    C'est la base de l'utilisation d'un débugueur.
    Ben, oui !!!

    Merci beaucoup

  10. #510
    Membre éclairé Avatar de Laurent_B_
    Homme Profil pro
    Ingénieur de déploiement réseaux
    Inscrit en
    Avril 2021
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur de déploiement réseaux
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 786
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void Saison::afficher_Saison(fs::path const& cheminFichier)
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void Saison::afficher_Episodes(fs::path const& cheminFichier)
    La question ?

    Et serie.h (class Saison et Serie) ???

    Merci

  11. #511
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 507
    Par défaut
    Pouvez-vous être plus précis dans vos questions, SVP ?
    Comme on ne sait ce qui vous bloque, on ai obligé de donner plein "d'explications".
    Là, on doit essayer de deviner ce que vous ne comprenez pas, c'est pas simple.

    On va donc se concentrer sur ce qui empêche le code de compiler.
    (Mais prenez la peine de nommer vos variables/champs/fonctions avec leur rôle (à quoi elles servent) pas avec leur types (sauf si le type renseigne leur rôle), SVP)

    C'est la ligne 773 de "serie.cpp" qui ne compile pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::wcout << saisons[i].saison.dos << std::end;
    ("std::end" c'est différent de "std::endl", c'est "std::endl" qu'il faut mettre à la fin de la ligne)

    C'est logique qu'une série contienne un ensemble de saison, donc le champ "saisons" sous forme d'un "std::vector<Saison>" dans la classe Serie, c'est aussi logique.
    Maintenant, c'est quoi le rôle du champ "saison" dans la classe Saison ?
    Idem pour le champ "dos" de cette même classe Saison ?
    On pourra corriger la syntaxe mais pour que cela compile mais il faudrait reprendre la conception de la classe Saison pour n'y mettre que des choses liées à un objet de type Saison et pas tout et n'importe quoi.

    Tel que le code est écrit, vous cherchez à accéder au champ "saison" de l'objet "saisons[i]".
    Vous êtes dans une fonction de la classe Serie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void Serie::PrintSaisons()
    Donc "saisons" correspond au champ "saisons" de la classe Serie, qui est de type "std::vector<Saison>".
    Donc "saisons[i]" est un objet de type Saison.
    En ajoutant ".saison", vous cherchez donc à accéder au champ "saison" de l'objet "saisons[i]".
    Ce champ "saison" est privé à la classe Saison (section "private" dans la déclaration de la classe Saison).
    Il n'est donc accessible que depuis des fonctions de la classe Saison, ce qui n'est pas le cas de la fonction "void Serie:rintSaisons()".
    Donc, si vous voulez utiliser ce champ "saison" depuis une fonction d'une autre classe, il faut le mettre dans la section "public" de la classe Saison.
    Je ne sais pas si c'est une bonne idée car on ne sait pas à quoi sert ce champ.
    En ajoutant ".dos", vous cherchez à accéder au champ "dos" de l'objet saison de type "std::pair<unsigned short int, std::wstring>", champ de l'objet saisons[i].
    Or "std::pair<unsigned short int, std::wstring>" n'a pas de champ "dos", d'où une autre erreur de compilation.

    Donc, c'est soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::wcout << saisons[i].dos << std::endl;
    soit, contenu du type du champ "saison" qui n'est pas directement affichable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     std::wcout << saisons[i].saison.first << L"," << saisons[i].saison.second << std::endl;
    Voir les 2 lignes si vous voulez afficher le contenu des 2 champs.

    Pensez à migrer la déclaration du ou des champs dans la section "public" de la déclaration de la classe "Saison" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Saison
    {
    public:
        Saison(void);
        ~Saison();
    ...
        std::wstring dos = L"";
        std::pair<unsigned short int, std::wstring>saison;
    ...
    private:
    ...
    }
    Ne migrez que les champs que vous voulez visible de l'extérieur de l'objet "Saison".

    void Print() et void PrintSaisons() ???
    Problème !!! Pas compris !
    Quel est le problème ?
    "Serie:rint()" utilise (en l'appelant) la fonction "Serie:rintSaisons".
    Où est le problème ?

    Ok : (dossier 1 et 2)
    XXXX-YY-ZZ 1
    XXXX-YY-ZZ 2
    1 et 2 ou un autre !!!
    J'ai oublié !
    Je ne vois aucun dossier qui utilise ce format dans le dépôt Git, je ne comprends pas votre remarque.

    Alors : std::pair<std::tm, std::wstring>dossier; : ok !
    Non, "dossier" n'indique pas la fonction du champ, et le type du champ (std::pair<std::tm, std::wstring>) n'a pas grand-chose avoir avec un dossier dans le système de fichier.
    Nommez vos variable/champs/fonctions correctement, BORDEL.

    Après, plus tard !!!
    NON, c'est maintenant que vous devez nommer vos variable/champs/fonctions correctement, BORDEL.

  12. #512
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 507
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void Saison::afficher_Saison(fs::path const& cheminFichier)
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void Saison::afficher_Episodes(fs::path const& cheminFichier)
    Quelle est la question ?
    Pourquoi choisir ?

    "Saison::afficher_Saison", c'est un peu redondant ; "Saison::afficher" ça serait aussi claire.

    Après, je ne pense pas que passer un paramètre à ces fonction, ça soit très pertinent, mais on verra ça plus tard.

    Et serie.h (class Saison et Serie) ???
    Quelle est la question ?

    Je mettrais les classes Serie et Saison dans des fichiers différents : Serie.h/.cpp et Saison.h/.cpp .

  13. #513
    Membre éclairé Avatar de Laurent_B_
    Homme Profil pro
    Ingénieur de déploiement réseaux
    Inscrit en
    Avril 2021
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur de déploiement réseaux
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 786
    Par défaut
    Bonsoir,

    struct Saison : Ok !

    https://github.com/laurentbouleau/Exemple : Février 20 et pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::wcout << blablabla << std::endl;
    Je suis crevé !!!

    Demain :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        void afficher_Episode(std::filesystem::path const& cheminFichier);
        void afficher_Episode_Titre(std::filesystem::path const& cheminFichier);
    Merci beaucoup

  14. #514
    Membre éclairé Avatar de Laurent_B_
    Homme Profil pro
    Ingénieur de déploiement réseaux
    Inscrit en
    Avril 2021
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur de déploiement réseaux
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 786
    Par défaut
    Bonsoir,

    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
    struct Saison
    {
    public:
        Saison(void);
        ~Saison();
        void afficher(std::filesystem::path const& cheminFichier);
        void afficher_Avec(std::filesystem::path const& cheminFichier);
        void afficher_Dossier(std::filesystem::path const& cheminDossier);
        void afficher_Fichier(std::filesystem::path const& cheminFichier);
        void afficher_Episode(std::filesystem::path const& cheminFichier);
        void afficher_Episode_Titre(std::filesystem::path const& cheminFichier);
        void afficher_Note(std::filesystem::path const& cheminFichier);
        void afficher_Titre(std::filesystem::path const& cheminFichier);
     
        //unsigned short int episode{ 0 };
        std::vector<std::pair<std::wstring, std::wstring>> avec;
        std::pair<std::tm, std::wstring>dossier;
        //                               x             e          dr                 streaming
        std::vector<std::tuple<unsigned int, unsigned int, std::vector<DateRecord>, std::wstring>>episode;
        //                               x           t1            t2           t3           temps      p
        std::vector<std::tuple<unsigned int, std::wstring, std::wstring, std::wstring, std::tm, std::wstring>> episode_titre;
        std::vector<std::wstring> image;
        double note = -1.0;
        std::pair<unsigned short int, std::wstring>saison;
        std::wstring titre;
    };
     
    class Serie
    {
    public:
        Serie(std::filesystem::path racine);
        ~Serie();
        const void Print();
        std::vector<Saison>saisons{};
        std::filesystem::path getRacine() { return racine; };
        std::filesystem::path getFileName() { return racine.filename(); };
    private:
        //const bool PrintDate_ou_Dates();
        //void PrintAvec(const std::vector<std::pair<std::wstring, std::wstring>> avec);
        const void PrintEpisodes(Saison saison);
        const void PrintSaison(Saison saison);
        const void PrintSaison_Date_etc(Saison saison);
        const void PrintSaisons();
     
        std::filesystem::path racine;
     
        std::vector<std::wstring>keyColor{ L"\x1b[94;1m", L"\x1b[38;2;0;255;0m" }; // keyColor[0] (bleu) et keyColor[1] (vert)
        std::wstring valuesColor = L"\x1b[38;2;255;255;255m"; // Blanc
     
        //bool affichage;
        bool afficage_Avec_actif = true;
        bool affichage_Episodes_actif = true;
        bool affichage_Saison_actif = true;
        bool affichage_Saison_Date_etc_actif = true;
        bool affichage_Saisons_actif = true;
    };
    Je suis crevé !!!

    Mais (serie.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
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    void Saison::afficher_Episode(fs::path const& cheminFichier)
    {
        auto nomFichier = cheminFichier.filename().wstring();
     
        assert(nomFichier.length() > 0 && L"Nom de fichier vide");
        std::size_t pos = 0;
        std::wstring strRestant = nomFichier.substr(pos);
        pos = strRestant.length();
        strRestant = strRestant.substr(0, pos - 4);
        pos = strRestant.length();
        assert((strRestant.length() < (9 + saison.first + 1)) && L"Nom de fichier trop court pour avoir au moins une date");
     
        pos = 0;
        unsigned int x = std::stoi(strRestant, &pos);
        if (saison.first == x && x >= 1000)
        {
            std::wcout << L"x <= 1000 !!!" << std::endl;
            exit(1);
        }
        pos = strRestant.find(L"x", 0);
        if (pos == std::wstring::npos)
        {
            std::wcout << L"Saison::afficher_Episode() :  x !!!" << std::endl;
            exit(1);
        }
        strRestant = strRestant.substr(pos + 1);
        if (x >= saison.first)
        {
            std::wcout << L"saison.first != x" << std::endl;
            exit(1);
        }
        unsigned int e = stoi(strRestant.substr(0, pos + 1));
        pos = strRestant.find(L'.');
        pos++;
        strRestant = strRestant.substr(pos);
        std::vector<DateRecord> dr;
        std::wstring streaming = L"";
     
        wchar_t sp = L' ', tiret = L'-', tiret_bas = L'_';
        int y, m, d;
     
        int firstYear = 0, firstMon = 0, firstDay = 0;
        int i = 0;
        do
        {
            if (strRestant[0] == sp)
            {
                if (strRestant[1] == std::wstring::npos || strRestant[1] == sp)
                {
                    // try cath !!!
                    // Explique-moi ??? 
                    // ou : 
                    exit(1);
                }
                strRestant = strRestant.substr(1);
                // try cath !!!
                // Explique-moi ??? 
                // ou : 
                try // Erreur !!!
                {
                    test_sp_et_npos_ou_pas_isblank(strRestant[0], isblank(strRestant[1]));
                }
                catch (exception_test_sp_et_npos_ou_pas_isblank e)
                {
                    exit(1);
                }
                if (strRestant.length() > 0)
                {
                    streaming = strRestant;
                }
                strRestant = L"";
                break;
            }
            if (!isdigit(strRestant[0]))
            {
                // try cath !!!
                // Explique-moi ??? 
                // ou : 
                exit(1);
            }
            // year + mon + mday
            if ((y = stoi(strRestant.substr(0, 4))) && checkyear(y)
                &&
                strRestant[4] == tiret
                &&
                (m = std::stoi(strRestant.substr(5, 2))) && checkmonth(m)
                &&
                strRestant[7] == tiret
                &&
                (d = std::stoi(strRestant.substr(8, 2))) && checkday(m, d, y)
                &&
                firstYear < y)
            {
                assert(firstYear < y && L"L'année aaaaa");
                firstYear = y;
                assert(firstMon < m && L"Le mois aaaaa");
                firstMon = m;
                assert(firstDay <= d && L"Le jours aaaaa");
                firstDay = d;
                dr.push_back(DateRecord{ 0 });
                dr[i].date.tm_year = y - 1900;
                dr[i].date.tm_mon = m - 1;
                dr[i].date.tm_mday = d;
                strRestant = strRestant.substr(10);
                if (strRestant[0] == tiret_bas)
                {
                    dr[i].someFlag = true;
                    strRestant = strRestant.substr(1);
                }
                i++;
                continue;
            }
            // mon + mday
            if ((m = std::stoi(strRestant.substr(0, 2))) && checkmonth(m)
                &&
                strRestant[2] == tiret
                &&
                (d = std::stoi(strRestant.substr(3, 2))) && checkday(m, d, firstYear)
                &&
                firstMon < m)
            {
                assert(firstMon < m && L"Le mois aaaaa");
                firstMon = m;
                dr.push_back(DateRecord{ 0 });
                dr[i].date.tm_year = firstYear - 1900;
                dr[i].date.tm_mon = m - 1;
                dr[i].date.tm_mday = d;
                assert(firstDay <= d && L"Le jours aaaaa");
                firstDay = d;
                strRestant = strRestant.substr(5);
                if (strRestant[0] == tiret_bas)
                {
                    dr[i].someFlag = true;
                    strRestant = strRestant.substr(1);
                }
                i++;
                continue;
            }
            // mday
            if ((d = std::stoi(strRestant.substr(0, 2))) && checkday(firstMon, d, firstYear)
                &&
                firstDay <= d)
            {
                firstDay = d;
                assert(firstDay <= d && L"Le jours aaaaa");
                dr.push_back(DateRecord{ 0 });
                dr[i].date.tm_year = firstYear - 1900;
                dr[i].date.tm_mon = firstMon - 1;
                dr[i].date.tm_mday = d;
                strRestant = strRestant.substr(2);
                if (strRestant[0] == tiret_bas)
                {
                    dr[i].someFlag = true;
                    strRestant = strRestant.substr(1);
                }
                i++;
                continue;
            }
            // try cath !!!
            // Explique-moi ???
            // ou : 
            exit(1);
        } while (strRestant.length() > 0);
        episode.push_back(make_tuple(x, e, dr, streaming));
        afficher_Episode_Titre(cheminFichier);
    }
    Et :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        //                               x             e          dr                 streaming
        std::vector<std::tuple<unsigned int, unsigned int, std::vector<DateRecord>, std::wstring>>episode;
    Fatigué !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        unsigned int e = stoi(strRestant.substr(0, pos + 1)); // ???
    Merci

  15. #515
    Membre éclairé Avatar de Laurent_B_
    Homme Profil pro
    Ingénieur de déploiement réseaux
    Inscrit en
    Avril 2021
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur de déploiement réseaux
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 786

  16. #516
    Membre éclairé Avatar de Laurent_B_
    Homme Profil pro
    Ingénieur de déploiement réseaux
    Inscrit en
    Avril 2021
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur de déploiement réseaux
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 786
    Par défaut
    Bonjour Bacelar,

    https://github.com/laurentbouleau/Exemple : Février 22

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::wcout << blablabla << std::endl;
    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
    const void Serie::PrintEpisodes(Saison saison)
    {
        if (affichage_Episodes_actif /* && dates.size() > 0*/)
        {
            wchar_t date_string[15];
            std::size_t taille;// , taille2;
            taille = std::size(saison.episode);
            std::wstring wstr;
            std::tm tm;
            for (int i = 0; i < taille; i++)
            {
                wstr = L"";
                //std::vector<std::tuple<unsigned int, unsigned int, std::vector<DateRecord>, std::wstring>>episode;
                //episode.push_back(make_tuple(x, e, dr, streaming));
                wstr += std::to_wstring(get<0>(saison.episode[i])) + keyColor[1] + L'x' + valuesColor;
                wstr += std::to_wstring(get<1>(saison.episode[i]));
                //
                wstr += keyColor[1] + L" : " + valuesColor;
                //                               x           t1            t2           t3           temps      p
                //std::vector<std::tuple<unsigned int, std::wstring, std::wstring, std::wstring, std::tm, std::wstring>> episode_titre;
                std::wstring t2 = get<2>(saison.episode_titre[i]);
                if (t2 == L"")
                    wstr += keyColor[1] + get<1>(saison.episode_titre[i]) + valuesColor;
                else
                    wstr += keyColor[1] + get<1>(saison.episode_titre[i]) + valuesColor + get<2>(saison.episode_titre[i]) + keyColor[1] + get<3>(saison.episode_titre[i]) + valuesColor;
                // Temps
                tm = get<4>(saison.episode_titre[i]);
                wstr += keyColor[1] + L" (" + valuesColor + std::to_wstring(tm.tm_min) + keyColor[1] + min + L')';
                // L" : "
                wstr += keyColor[1] + L" : " + valuesColor;
                //
                std::wcout << wstr << std::endl;
     
                // saison.episode_titre
                //std::wcout << get<5>(saison.episode_titre[i]) << std::endl;
                PrintEpisodes_Titres(saison);
            }
        }
    }
    Ok !

    You (après) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Console_Lire(hOut, blablabla + L"\r\n", x + c + 5, L' ');
    Ok !

    Pas dormir !!! Je suis fatigué !

    Merci

  17. #517
    Membre éclairé Avatar de Laurent_B_
    Homme Profil pro
    Ingénieur de déploiement réseaux
    Inscrit en
    Avril 2021
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur de déploiement réseaux
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 786
    Par défaut
    Bonsoir,

    Exemple :
    3x03.2024-02-22.txt
    Blablabla
    et :
    3x03.2024-02-23.txt
    Vide !!!
    Ben oui ! Mais : Erreur !!!

    Exemple.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    const std::vector<std::wstring> lire_fichierTxt(std::wstring const& nomFichier, std::vector<std::wstring> separeteurs)
    {
        std::string contenuFichier{ u8"" };
        std::string ligneCourante{ u8"" };
        std::vector<std::wstring> retVal{};
    
        ifstream fichier{ nomFichier };
    ...
        if (contenuFichier == u8"")
        {
            throw std::runtime_error("Le fichier '" + wstr_to_u8(nomFichier) + "' est vide."); // Ici !!!
        }
    ...
    Par exemple : You :
    Sweet Home.[2020- Netflix]
    2020-12-18
    1x10.2020-12-28.txt
    blablabla
    1x10.2023-12-16.txt
    Vide !!!
    Ok !

    Comment faire ?

    Merci d'avance

  18. #518
    Membre éclairé Avatar de Laurent_B_
    Homme Profil pro
    Ingénieur de déploiement réseaux
    Inscrit en
    Avril 2021
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur de déploiement réseaux
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2021
    Messages : 786
    Par défaut
    https://github.com/laurentbouleau/Exemple : Février 23
    J'ai oublié !!!

  19. #519
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 507
    Par défaut
    Votre fonction "afficher_Episode" est bien trop complexe pour ce quel est "sensée" faire.
    Le champ "saison" de la classe Saison n'a aucun sens précis, et est mal initialisé pour que "saison.first" dans la fonction "afficher_Episode" soit correct.
    Comme le nom du champ n'a rien de descriptif, il m'est impossible de corriger efficacement le problème en amont (je le redis, prenez le temps de correctement nommer les choses. BORDEL !!!).

    J'ai pris la solution de facilité de faire passer un paramètre "prefixe" à la fonction "afficher_Episode" qui correspond à l'usage de "saison.first" dans la fonction.
    J'ai bricolé un code qui permet de passer les "bonnes" valeurs pour ce paramètre pour les données fournis dans de dépôt.
    Mais vérifiez le fonctionnement des fonctions AVANT de vous en servir dans d'autres fonctions.

    Percept de base, n'utiliser des fonctions/classes/etc... qu'après avoir valider que ceux-ci fonctionnent comme prévu, sinon, vous êtes en train de faire une tour de Pise.

    On n'utilise quasiment jamais "exit". Justifiez-moi son utilisation partout dans votre code, SVP ?

    Après, l'utilisation d'assert ou du lancement d'une exception, c'est en fonction de si le problème est lié à une erreur de programmation ou dans les données fournis par l'utilisateur.
    A la vue du bordel dans les répertoires, je considère que c'est des erreurs de programmation si on se retrouve à appeler une fonction sur un fichier qui ne convient pas.

    Je fournis une implémentation "simplifié" de "afficher_Episode" (beaucoup des assert correspondent à vos "exit" et autres assert mais ils n'ont pas pour moi beaucoup de sens):
    Simplifié en termes de maintenabilité et de robustesse du code.
    J'ai ajouté un prefix 'fucking_" quand vous abusez sur le nom des champs ou de variables complétement incompréhensibles.
    J'ai utilisé les expressions régulières (RegEx) car beaucoup de votre code est inutilement complexe et serait grandement simplifié en les utilisant à la place de manipulation de chaines.
    L'utilisation du type "std::tm" n'est, pour moi, pas judicieux car limité et complexifie inutilement le code.
    (Le code est un peu plus complexe que prévu lié à une limitation du C++ au niveau des RegEx)
    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
     
    ...
    #include <regex>
    ...
     
    void Saison::afficher_Episode(unsigned short int prefixe, fs::path const& cheminFichier)
    {
        const std::wstring numero_saison_format = L"([[:digit:]]+)";
        const std::wstring sep_numero_saison = L"x";
        const std::wstring numero_episode_format = L"([[:digit:]]{1,3})";
        const std::wstring sep_episode_saison = L"\\.";
     
        const std::wstring date_year_month_day_format = L"([[:digit:]]{4})-([[:digit:]]{2})-([[:digit:]]{2})";
        const std::wstring date_month_day_format = L"([[:digit:]]{2})-([[:digit:]]{2})";
        const std::wstring date_day_format = L"([[:digit:]]{2})";
        const std::wstring stream_format = L"(\\s(.+))?";
        const std::wstring dates_format = L"((" + date_year_month_day_format + L"|" + date_month_day_format + L"|" + date_day_format + L")(_?))";
     
        const int dates_full_match_index = 0;
        const int dates_date_year_month_day_year_index = dates_full_match_index + 3;
        const int dates_date_year_month_day_month_index = dates_date_year_month_day_year_index + 1;
        const int dates_date_year_month_day_day_index = dates_date_year_month_day_month_index + 1;
        const int dates_date_month_day_month_index = dates_date_year_month_day_day_index + 1;
        const int dates_date_month_day_day_index = dates_date_month_day_month_index + 1;
        const int dates_date_day_day_index = dates_date_month_day_day_index + 1;
        const int dates_fucking_someFlag_index = dates_date_day_day_index + 2;
     
        const std::wregex filename_format_rg{ numero_saison_format + sep_numero_saison + numero_episode_format + sep_episode_saison + L"(" + dates_format +L"+)" + stream_format};
     
        const int filename_full_match_index = 0;
        const int filename_numero_saison_index = filename_full_match_index + 1;
        const int filename_numero_episode_index = filename_numero_saison_index + 1;
        const int filename_dates_index = filename_numero_episode_index + 1;
        const int filename_date_year_month_day_year_index = filename_dates_index + 2;
        const int filename_date_year_month_day_month_index = filename_date_year_month_day_year_index + 1;
        const int filename_date_year_month_day_day_index = filename_date_year_month_day_month_index + 1;
        const int filename_date_month_day_month_index = filename_date_year_month_day_day_index + 1;
        const int filename_date_month_day_day_index = filename_date_month_day_month_index + 1;
        const int filename_date_day_day_index = filename_date_month_day_day_index + 1;
        const int filename_fucking_someFlag_index = filename_date_day_day_index + 2;
        const int filename_stream_index = filename_fucking_someFlag_index + 2;
     
     
        auto nomFichier = cheminFichier.filename().wstring();
        assert(nomFichier.length() > 0 && L"Nom de fichier Episode vide");
     
        auto stem = cheminFichier.stem().wstring();
        assert((stem.length() > (9 + std::to_wstring(prefixe).length() + sep_numero_saison.length())) && L"Nom de fichier Episode trop court pour avoir au moins une date");
     
        assert(isdigit(stem[0]) && L"Nom de fichier Episode ne commençant pas par un nombre");
        unsigned int fucking_x = std::stoi(stem);
        assert((prefixe == fucking_x && fucking_x <= 1000) && L"x <= 1000 !!!");
        assert((stem.find(L"x", 0) != std::wstring::npos) && L"Saison::afficher_Episode() :  x !!!");
        assert(((fucking_x >= prefixe)) && L"saison.first != x");
        assert(std::regex_match(stem,filename_format_rg) && L"Le nom du fichier n'est pas valide");
     
        unsigned int fucking_e;
        std::vector<DateRecord> drS;
        std::wstring streaming = L"";
     
        std::wsmatch match;
        auto str = stem;
        //Exemple assez complexe de nom de fichier
        //str = L"1x01.2024-02-01_2024-02-02_02-03_0405 Netflix";
        std::regex_match(str, match, filename_format_rg);
     
        std::wsmatch dates_match;
        auto dates_str = match[filename_dates_index].str();
        while (std::regex_search(dates_str, dates_match, std::wregex{dates_format}))
        {
            if (dates_match[dates_date_year_month_day_year_index].matched)
            {
                auto year = std::stoi(dates_match[dates_date_year_month_day_year_index]);
                auto month = std::stoi(dates_match[dates_date_year_month_day_month_index]);
                auto day = std::stoi(dates_match[dates_date_year_month_day_day_index]);
     
                assert(checkyear(year));
                assert(checkmonth(month));
                assert(checkday(month, day, year));
     
                DateRecord dr{ {0,0,0,day,month - 1,year - 1900} };
     
                drS.emplace_back(dr);
            }
            else if(dates_match[dates_date_month_day_month_index].matched)
            {
                assert(drS.size()>0 && L"Utilisation d'un format mois-jour sans avoir d'année déduite.");
     
                auto month = std::stoi(dates_match[dates_date_month_day_month_index]);
                auto day = std::stoi(dates_match[dates_date_month_day_day_index]);
     
                auto lastDateRecord = drS.back();
                auto last_year = lastDateRecord.date.tm_year + 1900;
     
                assert(checkmonth(month));
                assert(checkday(month, day, last_year));
     
                DateRecord dr{ {0,0,0,day,month - 1,last_year - 1900} };
     
                drS.emplace_back(dr);
            }
            else if (dates_match[dates_date_day_day_index].matched)
            {
                assert(drS.size() > 0 && L"Utilisation d'un format jour sans avoir de mois et d'années déduits.");
     
                auto day = std::stoi(dates_match[dates_date_day_day_index]);
     
                auto lastDateRecord = drS.back();
                auto last_year = lastDateRecord.date.tm_year + 1900;
                auto last_month = lastDateRecord.date.tm_mon + 1;
     
                assert(checkday(last_month, day, last_year));
     
                DateRecord dr{ {0,0,0,day,last_month - 1,last_year - 1900} };
     
                drS.emplace_back(dr);
            }
            else
            {
                assert(true && L"format de date d'épisode inconnu.");
            }
     
            if (dates_match[dates_fucking_someFlag_index].matched)
            {
                drS.back().someFlag = true;
            }
     
            dates_str = dates_match.suffix().str();
        }
     
        if (match[filename_stream_index].matched)
        {
            streaming = match[filename_stream_index];
        }
     
        fucking_e = std::stoi(match[filename_numero_episode_index]);
     
        episode.push_back(make_tuple(fucking_x, fucking_e, drS, streaming));
        afficher_Episode_Titre(cheminFichier);
    }
    L'usage des RegEx peut vous semblez complexe mais ici, on n'est dans un cas où le format des noms de fichier est particulièrement complexe.
    Avec des formats plus simples, le code sera très lisible.
    Et si on a mal compris un détail dans votre format de nom de fichier, adapter l'expression régulière sera facile.

    On n'a un fichier avec un nom "1x03.2024-02-02_02.txt", c'est normal qu'on eut 2 fois la même date pour le même épisode ???


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        //                               x             e          dr                 streaming
        std::vector<std::tuple<unsigned int, unsigned int, std::vector<DateRecord>, std::wstring>>episode;
    Très moyen comme type de champ, ainsi que son nom (BORDEL!!!).
    Il y a potentiellement plusieurs épisodes donc un nom comme "episodes" ou "list_episodes" serait plus clair.
    Le type n'est pas très bon non plus, car il permet d'avoir des épisodes avec le même numéro (le second membre du tuple), et l'information dans le premier membre du tuple (le numéro de la saison) n'a rien à faire avec un épisode, c'est une information qui doit être contenue dans la Saison (ou déduite depuis l'objet Serie).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unsigned int e = stoi(strRestant.substr(0, pos + 1)); // ?
    Compliqué pour rien, et casse-gueule, utilisez mon exemple dans la fonction "Saison::afficher_Episode' ci-avant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const void Serie::PrintEpisodes(Saison saison){...}
    Votre fonction "Serie:: PrintEpisodes" est complètement bogué.
    Elle appelle "Serie:: PrintEpisodes_Titres(Saison saison)" qui affiche tous les titres, pas celui de l'épisode courant.
    A chaque épisode vous affichez les titres de tous les épisodes.
    Vous deviez avoir une fonction dédiée à l'affichage du titre d'un épisode. En passant le numéro d'épisode en paramètre, par exemple.

    "Serie:: PrintEpisodes_Titres(Saison saison)" n'est pas exempt de bugs non plus, car elle utilise "std::size(saison.episode)" pour avoir la taille au lieu de "std::size(saison.episode_titre)".

    Je pense qu'avoir 2 champs pour les épisodes dans un objet "Saison" : "episode" et "episode_titre", est une grosse connerie. Toutes les informations sur un Episode devraient être dans un seul objet, quitte à faire une classe Episode dédiée.
    Utilisez "std::format" pour simplifier le code de ce type de fonction.

  20. #520
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 507
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 507
    Par défaut
    Comment faire ?
    Je ne comprends pas trop la question.
    Vous avez ajouté le fichier "Better Call Saul.[2015-2022]\2017-04-10\3x03.2024-02-23.txt" dans le dépôt.
    Mais ce fichier est vide.

    Donc, c'est "normal" que l'exception se lance à la ligne 201 d'Exemple.cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    throw std::runtime_error("Le fichier '" + wstr_to_u8(nomFichier) + "' est vide.");
    Comme "contenue" est vide, car le fichier est vide.

    Donc, avec votre code, un fichier ne peut pas être vide.

    Alors il peut ou il ne peut pas être vide ?

    Faut se décider.

    PS : Attention, vous avez tags 2 version avec le même nom/tag : "Février 23".

+ 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