Courage
Courage
Oh, ça va ! Et, bon fête !!!
Pour : bug/Erreur : plus tard !
Donc Console (console.h et console.cpp) :
Gravité Code Description Projet Fichier Ligne État de la suppression
Erreur C2065 'm_hOut'*: identificateur non déclaré You D:\Work\Prg\CPP\You 1\console.cpp 100Alors, que faire ?
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 // ###################################################################################################################################################### // # # // # PrintStringW # // # const void Console::PrintStringW(HANDLE hOut, const std::wstring& str) # // # # // ###################################################################################################################################################### const void Console::PrintStringW(HANDLE hOut, const std::wstring& str) { DWORD dwMode = 0; BOOL res = WriteFile( hOut, &str[0], (DWORD)(str.size() * sizeof(wchar_t)), &dwMode, NULL); assert(res == TRUE); } // ###################################################################################################################################################### // # # // # PrintStringW # // # const void Console::PrintNationalites(const std::vector<std::wstring>& nationalites, # // # std::wstring& sous_genre, # // # std::wstring& titre_T, std::wstring& titre_t, bool nationalite_) # // # # // ###################################################################################################################################################### const void Console::PrintNationalites(const std::vector<std::wstring>& nationalites, std::wstring& sous_genre, std::wstring& titre_T, std::wstring& titre_t, bool nationalite_) { if (nationalite_ == true && nationalites.size() > 0) { std::wstring nationalite_str = titre_T + L"Nationalite" + ((nationalites.size() > 1) ? L"s" : L"") + L" : " + titre_t; bool first = true; for (auto&& nationalite : nationalites) { if (!first) { nationalite_str += titre_T + L", " + titre_t; } nationalite_str += nationalite; first = false; } if (sous_genre.size() != 0) nationalite_str += L' ' + titre_T + L'(' + titre_t + sous_genre + titre_T + L')' + titre_t; nationalite_str += L"\r\n"; PrintStringW(m_hOut, nationalite_str); } }
Mais : You.cpp
------------
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 // ... HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); DWORD dwMode = 0; CONSOLE_SCREEN_BUFFER_INFO csbiInfo; // ...
console.h
Merci pour tous
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 #pragma once #include "Utils.h" #include "titre.h" #include "You.h" #include "you_txt.h" #include "cinema.h" #include "serie.h" #include "erreur_ok.h" #include "Bug.h" #include <windows.h> #include <cassert> #include <stdexcept> #include <string> #include <algorithm> #include <vector> #include <iostream> #include <sstream> #include <ctime> #include <codecvt> #include <filesystem> // C++17 standard header file name #include <experimental/filesystem> // Header file for pre-standard implementation class Console { public: Console(void); ~Console(); const void PrintStringW(HANDLE hOut, const std::wstring& str); static void affiche_CleValeur(std::wstring cle, std::wstring valeur); // c'est beaucoup plus logique, voir ci-après const void PrintNationalites(const std::vector<std::wstring>& nationalites, std::wstring& sous_genre, std::wstring& titre_T, std::wstring& titre_t, bool nationalite_); const void PrintCreee_par(const std::vector<std::wstring>& creee_par, std::wstring titre_T, std::wstring titre_t, bool creee_par_); protected: //static const std::wstring Text_Color = L"\x1b[38;2;255;0;0m"; // ??? /*static*/ const std::wstring Text_Color = L"\x1b[38;2;255;0;0m"; // Ok ! Problème ! //static const std::wstring Default_Color = L"\x1b[38;2;255;255;255m"; //static const std::wstring Ponctuation_Color = L"\x1b[38;2;0;200;200m"; //static const std::wstring End_Ln = L"\r\n"; private: static HANDLE getInstance();//le code d'implémentation, c'est pour après. //static HANDLE inst = NULL; // ??? /*static*/ HANDLE inst = NULL; };
Merci, pour vous aussi, de très bonnes fêtes de fin d'année.Oh, ça va ! Et, bon fête !!!
Ok, mais ne tardez pas trop. Ça pollue pas mal le code.Pour : bug/Erreur : plus tard !
J'ai pas de ligne 100 dans le "console.cpp " que vous avez envoyé via le zip.Donc Console (console.h et console.cpp) :
Gravité Code Description Projet Fichier Ligne État de la suppression
Erreur C2065 'm_hOut'*: identificateur non déclaré You D:\Work\Prg\CPP\You 1\console.cpp 100
Je suppose que c'est la ligne 50 de votre extrait.
Cela semble logique au regard de la ligne 46 de console.h que vous avez postée :
Code : Sélectionner tout - Visualiser dans une fenêtre à part PrintStringW(m_hOut, nationalite_str);
Dans la version que vous avez envoyé via le zip :
Code : Sélectionner tout - Visualiser dans une fenêtre à part /*static*/ HANDLE inst = NULL;
La déclaration de "m_hOut" a été remplacée par une ligne de commentaire en doublon (de la ligne 45 de console.h).
Code : Sélectionner tout - Visualiser dans une fenêtre à part static HANDLE m_hOut;// = NULL;
Cela explique l'erreur à la compilation (et non à l'exécution).
L'état actuel de la classe Console entraînerait surement des erreurs à l'exécution, mais les erreurs à la compilation semblent venir de modification dans le code, dont je ne comprends pas l’aspect "prioritaire" (ni même utile dans l'immédiat).
Comme vous avez indiqué que la classe Console était pour plus tard, je vous avais "concocté" les fonctions "PrintKeyValue/PrintTmp" à utiliser à la place de la classe Console "en attendant".
L'extrait de code de You.c que vous donnez est bien une partie du code qu'il faudrait transférer dans la classe Console, mais aussi la fonction "init" qui suit l'extrait.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 // ... HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); DWORD dwMode = 0; CONSOLE_SCREEN_BUFFER_INFO csbiInfo; // ...
Vous devriez mettre en commentaire tous les appels à des fonctions de la classe Console et faire un appel aux fonctions "PrintKeyValue/PrintTmp" à la place.
(Vous pouvez, dans Visual Studio, changer les propriétés d'un fichier pour qu'il ne soit plus "Inclus dans le Projet" => plus compilé pour un fichier .c ou .cpp)
Vous ne semblez pas suivre mes "directives" sur l'ordre des actions à faire, je ne suis pas sûr que votre ordre d'actions soit plus simple à la fin.
L'ajout de la fonction "PrintNationalites" dans la classe Console illustre pas mal des aspects que j'indiquais comme problématiques dans mon dernier message :
-Il faut mettre les fonctions dans les classes où cela "a un sens"
La "Nationalité" d'une série ou d'un film ça a un sens, pas pour une console (ou pas dans ce contexte)
=> Il faut donc que "PrintNationalites" soit dans la classe Serie et/ou dans la classe Cinema (qui devrait être la classe Film, je pense), voir dans une classe "Media" (classe mère des classes Serie et Cinema)
-Pourquoi ajouter du code (une fonction) a une classe qu'on doit "voir plus tard" ???
-L'utilisation de cartouche qui ne semble pas servir à grand-chose, sauf se désynchroniser du le code courant.
-Une signature de fonction complètement illogique sentant bon le copier-coller:
"sous_genre", vraiment ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 const void Console::PrintNationalites(const std::vector<std::wstring>& nationalites, std::wstring& sous_genre, std::wstring& titre_T, std::wstring& titre_t, bool nationalite_) { ... }
c'est quoi "titre_T", au juste ?
c'est quoi "titre_t", au juste, et la différence avec "titre_T" ?
"nationalite_" ça sert à quoi ? (Les exceptions sont nos amies)
Et surtout, "Printxxx", ça affiche et c'est tous. Le reste, comme la validation, c'est pas son taf.
Une fonction ne fait qu'une chose, ce qui est indiqué dans son nom, mais doit le faire "bien".
Donc, si on suit mes directive, "Console:rintNationalites" dégage et on n'a deux fonctions identiques (qu'on pourra fusionner quand la classe Media apparaîtra):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 void Cinema::PrintNationalites() { if (m_Nationalites.size() > 0) { PrintKeyMultipleValues (c_keyColor, "Nationalite" + ((m_Nationalites.size() > 1) ? L"s" : L""), c_valueColor, m_Nationalites); } }Et pour que le code de "xxxx:rintNationalites" soit simple, on n'utilise une nouvelle fonction utilitaire "PrintKeyMultipleValues", très semblable à "PrintKeyValue" :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 void Serie::PrintNationalites() { if (m_Nationalites.size() > 0) { PrintKeyMultipleValues (c_keyColor, "Nationalite" + ((m_Nationalites.size() > 1) ? L"s" : L""), c_valueColor, m_Nationalites); } }
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 void PrintKeyMultipleValues(const std::wstring& keyColor, const std::wstring& keyText, const std::wstring& valueColor, const std::vector<std::wstring>& values, const std::wstring& separatorKeyValues = L" : ", const std::wstring& separatorValuesValuesColor = L"", const std::wstring& separatorValuesValues = L", ") { std::wstring values_str = L""; for (auto & element : values) { if(values_str.size()>0) { values_str += separatorValuesValuesColor + separatorValuesValues; } values_str += valueColor + element; } PrintTmp(keyColor + keyText + separatorKeyValues + values_str ); }
P.S.:
Pourquoi la ligne 44 de console.h a été dé-commenté ?
P.P..S.: Les champs m_AudioDesc, m_Nationalites, etc... des classes Cinema et Serie devront être remplis au moment de la création de l'instance.
Code : Sélectionner tout - Visualiser dans une fenêtre à part static HANDLE getInstance();//le code d'implémentation, c'est pour après.
Bonsoir à tous, et bonne année 2023
Je sais ! Pas-à-pas
Bonsoir Bacelar,
Exemple : Drifting Dragons (série)
Utils.cpp
titre.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 void PrintGenres(const std::vector<std::wstring>& genres, bool genre_, const std::wstring& sous_genre, bool sous_genre_, std::wstring& titre_T, std::wstring& titre_t) { if (genre_ == true && genres.size() > 0) { std::wstring genre_str = titre_T + L"Genre" + ((genres.size() > 1) ? L"s" : L"") + L" : " + titre_t; bool first = true; for (auto&& genre : genres) { if (!first) { genre_str += titre_T + L", " + titre_t; } genre_str += genre; first = false; } if (sous_genre.size() != 0) genre_str += titre_T + L" et " + titre_t + sous_genre; genre_str += L"\r\n"; //PrintStringW(m_hOut, genre_str, 0); int i = Console_Lire_txt(genre_str, 0, 0); } }
Explication :
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>Genre { L"Action", L"Arts Martiaux", ... }; const std::vector<std::wstring> Sous_Genre { L"Animation", L"Documentaire", ... };
genre_ et sous_genre_ == true ou false :
pour plus tard : fonction ? Merci
titre_T et titre_t : couleurs !
std::wstring Text_Color et std::wstring Default_Color, mais :
et
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 class Serie { friend class Titre; ... private: ... bool S_Espace; // = false ou true; std::wstring S_MIN; // = L"min"; std::wstring S_T; std::wstring S_t; std::wstring S_W; std::wstring S_w; ... };
et
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 const int Serie::Ok_S(bool P_S_Espace, std::wstring P_S_MIN, std::wstring P_S_T, std::wstring P_S_t, std::wstring P_S_W, std::wstring P_S_w) { S_Espace = P_S_Espace; // = false ou true; S_MIN = P_S_MIN; // = L"min"; S_T = P_S_T; S_t = P_S_t; S_W = P_S_W; S_w = P_S_w; return EXIT_SUCCESS; }
S_T, S_t, S_W et S_w ???
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 struct Person { ... // min bool S_Espace = false; // true ou false std::wstring S_MIN = L"min"; // = L"min"; std::wstring S_T = L"\x1b[38;2;0;0;255m"; std::wstring S_t = L"\x1b[38;2;255;255;255m"; std::wstring S_W = L"\x1b[38;2;0;255;0m"; std::wstring S_w = L"\x1b[38;2;255;255;255m"; ... } P;
Solution ?
Merci avance
(plus tard )
J'espère que vous avez commencé la conception de "PrintGenres" APRES avoir implémenter les fonctions : "PrintTmp", "PrintKeyValue" et "PrintKeyMultipleValues".
En ayant ces 3 fonctions d'abord, vous pourrez très facilement réduire la complexité des fonctions de plus "haut niveau", comme "PrintGenres".
Vous avez fait de "PrintGenres" une fonction libre malgré le fait qu'un genre n'a de sens que sur un Media (Serie ou Cinema (=>Film)).
En faisant cela, vous êtes obligé de passer un grand nombre de paramètre à la fonction.
En faisant de cette fonction, un membre de la classe Serie et/ou Cinema (=>Film), ou encore de la classe Media, classe mère de Serie et Cinema (=>Film), vous ne seriez pas obligé de passer autant de paramètres.
Et faites un effort dur le nommage des paramètres d'une fonction, SVP !!!
Non, ces noms de paramètre sont imbitables.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 void PrintGenres(const std::vector<std::wstring>& genres, bool genre_, const std::wstring& sous_genre, bool sous_genre_, std::wstring& titre_T, std::wstring& titre_t) {...}
A la rigueur :
Le format de sortie de "PrintGenres" est assez proche du format de "PrintKeyMultipleValues", vous êtes sûr de ne pas avoir le même format ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 void PrintGenres(const std::vector<std::wstring>& genres, bool affichage_actif, const std::wstring& sous_genre, bool affichage_sous_genre_actif, std::wstring& keyColor, std::wstring& valuesColor) {...}
Il est possible de faire une fonction libre généraliste qui permettrait de générer un affichage comme celui de "PrintGenres", mais sans valeurs "en dur", qu'on pourrait nommer "PrintKeyMultipleValuesMultipleLevel".
Passer un paramètre comme "genre_"/"affichage_actif" à une fonction, pour d'activer/désactiver totalement les actions de la fonction n'a pas vraiment de sens.
Un appel comme :
Serait plus clair sous cette forme (je pense):
Code : Sélectionner tout - Visualiser dans une fenêtre à part PrintGenres(genres, affichage_genres_actif, sous_genres, affichage_sous_genre_actif, keyColor, valuesColor)
Votre gestion des sous-genres est bizarre car vous pouvez avoir plusieurs genres mais un seul sous-genre.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 if(affichage_genres_actif) { PrintGenres(genres, sous_genres, affichage_sous_genre_actif, keyColor, valuesColor) }
Moi, je mettrais genres et sous-genre comme multi-valué => un paramètre de type "const std::vector<std::wstring>&" pour chacun.
Le paramètre "affichage_sous_genre_actif" est redondant avec le paramètre "sous_genres", car il suffit de passer un std::vector vide dans le paramètre "sous_genres" pour avoir l'action équivalente à "affichage_sous_genre_actif == false".
Donc, en résumé, si PrintGenres doit rester une fonction libre :
Et on dégage cette cochonnerie de "Console_Lire_txt".
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 PrintGenres(const std::vector<std::wstring>& genres, const std::vector<std::wstring>&sous_genres, std::wstring& keyColor, std::wstring& valuesColor, std::wstring& separatorColor) { if (genres.size() > 0) { std::wstring genre_str = keyColor + L"Genre" + ((genres.size() > 1) ? L"s" : L"") + L" : " + valuesColor; bool first = true; for (auto&& genre : genres) { if (!first) { genre_str += separatorColor+ L", " + valuesColor; } genre_str += genre; first = false; } if (sous_genres.size() != 0) { genre_str += separatorColor + L" et " + valuesColor; first = true; for (auto&& sous_genre : sous_genres) { if (!first) { genre_str += separatorColor+ L", " + valuesColor; } genre_str += sous_genre ; first = false; } } genre_str += L"\r\n"; PrintTmp(genre_str); } }
En rendant "PrintGenres" fonction membre des classes Serie et "Cinema"(=>Film) ça simplifie encore plus le code :
Je ne vois pas le rapport entre "Titre" et les constantes "Genre" et "Sous_Genre".
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 PrintGenres() { if (m_genres.size() > 0) { std::wstring genre_str = c_keyColor + L"Genre" + ((m_genres.size() > 1) ? L"s" : L"") + L" : " + c_valuesColor; bool first = true; for (auto&& genre : m_genres) { if (!first) { genre_str += c_separatorColor+ L", " + c_valuesColor; } genre_str += genre; first = false; } if (m_sous_genres.size() != 0) { genre_str += c_separatorColor + L" et " + c_valuesColor; first = true; for (auto&& sous_genre : m_sous_genres) { if (!first) { genre_str += c_separatorColor+ L", " + c_valuesColor; } genre_str += sous_genre ; first = false; } } genre_str += L"\r\n"; PrintTmp(genre_str); } }
Si ces constantes sont différentes entre "Serie" et "Cinema"(=>Film), autant faire 2 ensembles de constantes différentes, une dans chaque classe (des constantes statiques de classe).
Si elles sont commune à "Serie" et "Cinema"(=>Film), autant les déclarer temporairement dans Utils.h/.cpp.
Encore mieux, ça sert à rien, on dégage.genre_ et sous_genre_ == true ou false :
Alors appelez ça "couleur" BORDEL !!!titre_T et titre_t : couleurs !
cf. les noms des paramètres "keyColor", "valuesColor" et "separatorColor" dans mes exemples de signatures de fonction.
Donc virez-moi ces champs et autres variables locales avec ces noms imbitables !!!
On vire et on utilise les constantes de "couleurs" (c_valuesColor, etc...)S_T, S_t, S_W et S_w ???
Bonsoir,
Vous :
et :Oh, ça va ! Et, bon fête !!!
Merci, pour vous aussi, de très bonnes fêtes de fin d'année.
Pour : bug/Erreur : plus tard !
Ok, mais ne tardez pas trop. Ça pollue pas mal le code.
...
P.P..S.: Les champs m_AudioDesc, m_Nationalites, etc... des classes Cinema et Serie devront être remplis au moment de la création de l'instance.
Vous : ok !J'espère que vous avez commencé la conception de "PrintGenres" APRES avoir implémenter les fonctions : "PrintTmp", "PrintKeyValue" et "PrintKeyMultipleValues".
...
S_T, S_t, S_W et S_w ???
On vire et on utilise les constantes de "couleurs" (c_valuesColor, etc...)
Mais moi compliqué !!!
Pas-à-pas, oui ou non ?
Exemple : (sous genre)
e:\Séries.[]\+++\D\Drifting Dragons.[2020 Netflix].Manga
ou
e:\Séries.[]\+++\D\Dragon Age- Absolution.[2022 Netflix].Animation
Donc : seul
www.allocine.fr et www.netflix.fr
Merci beaucoup
Ok.Pas-à-pas, oui ou non ?
Donc, toujours maintenir le code compilable et exécutable (les cas nominaux doivent toujours fonctionner, si possible).
Quand je dis de "dégager" un truc, c'est à dégager "à terme", pas tout de suite.
Mais quand vous faites du nouveau code ou que vous refactorez (modifier le code dans l'objectif de le rendre plus simple), évitez au maximum de vous en servir, quit à ajouter quelques fonctions supplémentaires dans Utils.h/.cpp.
Donc, commencez par implémenter les 4/5 fonctions ("LoadDataFromFile", "PrintTmp", "PrintKeyValue" et "PrintKeyMultipleValues", et peut-être "PrintGenres" si vous la voulez vraiment en fonction libre) dans Utils.h/.cpp.
Ajoutez dans Utils.h/.cpp, les constantes "std::wstring" correspondants aux couleurs que vous voulez utiliser => On pourra facilement ainsi dégager (pendant les refactoring) toutes ces cochonneries de "S_T, S_t, S_W et S_w ", etc... .
Comme votre code actuel n'utilise pas encore ces fonctions et couleurs, ajoutez dans votre fonction "main" (wmain) des appels à ces méthodes et des utilisations à ces constantes, histoire de voir qu'elles fonctionnent, sous forme de tests préliminaires.
Une fois que vous avez bien vérifié avec ces tests préliminaires qu'elles fonctionnent correctement vous pouvez enlever ces tests de votre fonction "main" (wmain).
Maintenant, il reste à vous en servir (les trucs dans Utils.h/.cpp) pendant l'ajout de nouvelles fonctionnalités ou de refactoring de votre code, à la place des trucs "à dégager à terme".
Pour pouvoir simplifier grandement votre code tout en ne cassant pas tout d'un coup, je vous conseille de commencer par ajouter un constructeur à la classe Serie ou à la classe Cinema (faudrait quand même penser à la renommer cette classe !!!) qui prend comme seul paramètre, un chemin vers un répertoire.
Ce répertoire dont on fournit le chemin, c'est la racine des fichiers qui contiennent les informations sur la Serie ou le Film et à la fin de l'appel du constructeur, l'objet aura récolté toutes les informations contenues dans les fichiers et mis dans les différents champs de l'objet.
La recherche des informations se fera comme dans le code de votre fonction "You_t", avec l'utilisation de "directory_iterator", mais au lieu d'afficher "bêtement" le contenu des fichiers, l'objet stockera les informations dans ses champs et utilisera ses champs dans le code de sa fonction membre "afficher".
En résumé, votre fonction "You_t" :
Se transformera en (Les variables globales comme "cinema" et autre "serie", faudrait aussi les dégager assez rapidement, via des constantes statiques de classes, par exemple) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 const int You_t(std::vector<std::wstring>&v) { //plein de choses sans cohérences évidentes }
Une fonction de plus de 20 lignes, ça doit être exceptionnel !!!
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 void You_t(std::vector<std::wstring>&argv) { if (argv[2] == L"c") { if (argv[3] != L"\0") { path racine {cinema.cs + argv[3]}; Cinema film{racine}; film.afficher(); } } else if(argv[2] == L"s") { if (argv[3] != L"\0") { path racine {serie.cs + argv[3]}; Cinema ma_serie{racine}; ma_serie.afficher(); } } }
Vous, vous les collectionnez car elles font bien trop de choses à la fois.
(mon code peut facilement être encore plus réduit en utilisant l'héritage et autres trucs, mais on verra ça plus tard.)
Pour le code du constructeur:
En procédant ainsi, le code reste simple.
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 Cinema::Cinema(const path& racine) { .... for (directory_iterator next(racine), end; next != end; ++next) { .... if(next.filename().compare(L"genres.txt")==0) { m_genres = ::LoadDataFromFile(next); } if(next.filename().compare(L"creepar.txt")==0) { m_creePar = ::LoadDataFromFile(next); } .... } .... }
Après, il faut implémenter la fonction membre "afficher" de la classe, qui n'utilisera que les champs "m_xxx" et nos fonctions utilitaires type "PrintTmp", Printxxx pour afficher les informations stockées dans les champs de l'instance d'objet dans la console du programme.
Je pense qu'avec ces constructeurs et fonction "afficher" implémentés, vous pourrez facilement sabrer dans tout le reste du code bien trop complexe pour rien.
Si la mise en place des constructeurs vous pose un problème, on peut encore découper la tâche, si nécessaire.
C'est bon pour vous ?
Sinon, pouvez-vous être un peu plus précis sur vos difficultés ?
Bonsoir,
Plus tard mais j'ai oublié !!!
Exemple :
Ok
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 const int Serie::afficher_Note(std::wstring& n_filename, std::wstring const& nomFichier, int& note, bool& note_) { // 0...100 ou -100 assert((n_filename == createdBy_filename) && L"Erreur !!! Note... !"); ... note = static_cast<int>(f * 20.0f); ... }
Mais :
Marche pas !
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 const std::wstring Serie::afficher_OK_Note() { int i, j = 0; // ??? int k = 0; // std::wstring t; float somme = 0, moyenne = 0; int pas_de_moyenne = 0, pas_de_note = 0; int n = 0; if (D_I == 0) { t = L' ' + keyColor + L'(' + valuesColor + L"pas de note !" + keyColor + L')' + valuesColor; return t; } else { for (i = 0; i < D_I; i++) { if (D_Note[i] == -1) { std::wcout << L"pas_de_note" << std::endl; pas_de_note += 1; continue; } else if (D_Note[i] == -100) { pas_de_moyenne += 1; continue; } else { somme += D_Note[i]; j++; k++; } } } // if (pas_de_note == D_I /*+ 1*/ && somme == 0) t = L""; else if (pas_de_moyenne <= 1 && somme == 0) { t = L' ' + keyColor + L'(' + valuesColor + L"pas de note !" + keyColor + L')' + valuesColor; } else { std::wstring wstr; if (j == 2) { // ???? Note = somme; //std::wcout << L"aaa Note=" << Note << std::endl; } else { //j -= 1; //j--; Note = somme / (k); } wstr = std::to_wstring(static_cast<float>(Note / 20)); if (wstr[2] == L'0' && wstr[3] == L'0') wstr = wstr[0]; else if (wstr[3] == L'0') wstr = wstr[0] + keyColor + wstr[1] + valuesColor + wstr[2]; else wstr = wstr[0] + keyColor + wstr[1] + valuesColor + wstr[2] + wstr[3]; t = L' ' + wstr + keyColor + L"/5" + valuesColor; } return t; }
wstr = std::to_wstring(static_cast<float>(Note / 20)); : ???et ???
Que faire ?
Merci d'avance
@laurent_b voilà une fonction pour convertir un réel vers un std::wstring ça fonctionne bien
sinon sur mon projet j'ai eu des crashes sans savoir pourquoi avec fwprintf_s
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 std::wstring ConvertDoubleToWString(double dd) { char szVal[100]; wchar_t wszVal[100]; std::wstring strTmp; int ret=0; sprintf_s (szVal,"%.2f",dd); ret=mbstowcs(wszVal,szVal,sizeof(wszVal)); strTmp=wszVal; return strTmp; }
J'utilise fputws au cas où vous utilisez cette fonction.
Bonjour,
Mat.M : Oh, merci
Sinon :
Ok :
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 const void Cinema::afficher_Note(std::wstring& n_filename, std::wstring const& nomFichier) { // 0...100 ou -100 std::wstring n = lire_fichierTxt(nomFichier); std::size_t pos = n.length(); if (n == L"") { note = -100; return; } if (pos != 1 && pos != 3) { E.afficher_X(-1, n, L"Pas de [a-z] et/ou [0-9] et/ou etc "); return; } if (!iswdigit(n[0])) { E.afficher_X(-1, n, L"Pas de [a-z] et/ou etc "); return; } if (!(n[0] == L'0' || n[0] == L'1' || n[0] == L'2' || n[0] == L'3' || n[0] == L'4' || n[0] == L'5')) { E.afficher_X(-1, n, L"Pas de [0-5]"); return; } if (pos == 1) note = 20 * std::stoi(n); else { if ((n[1] == L',' || n[1] == L'.') && iswdigit(n[2]) && pos == 3) { n[1] = L','; float f = std::stof(n); // Ok !!! note = static_cast<int>(f * 20.0f); } else { E.afficher_X(-1, n, L"Pas de "); return; } } return; }
note = static_cast<int>(f * 20.0f);
Mais :
Bizarre !!! Explication ?
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 const int Cinema::afficher() { // OK ! ... if (note_) { if (note == -100) Textes += L' ' + keyColor + L'(' + valuesColor + L"pas de note !" + keyColor + L')' + valuesColor; else { if (note == 0 || note == 20 || note == 40 || note == 60 || note == 80 || note == 100) Textes += L' ' + std::to_wstring((int)note / 20.0f); else { wstr = std::to_wstring(static_cast<float>(note / 20.0f)); wstr = wstr[0] + keyColor + wstr[1] + valuesColor + wstr[2]; Textes += L' ' + wstr; } Textes += keyColor + L"/5" + valuesColor; } Textes += std::to_wstring(note); } else { Textes += L' ' + keyColor + L'(' + valuesColor + L"pas de note !" + keyColor + L')' + valuesColor; } ... }
Merci d'avance
Pas Ok !!!Exemple :
Ok
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 const int Serie::afficher_Note(std::wstring& n_filename, std::wstring const& nomFichier, int& note, bool& note_) { // 0...100 ou -100 assert((n_filename == createdBy_filename) && L"Erreur !!! Note... !"); ... note = static_cast<int>(f * 20.0f); ... }
Code beaucoup trop complexe qui ne fait pas ce qui est indiqué dans son nom de fonction et fait plusieurs choses à la fois.
"createdBy_filename" qui n'a aucun sens ici, et les vérification n'ont rien à faire là.
Beaucoup trop de paramètres qui ne servent quasi à rien.
Les "cast" comme "static_cast" ne sont pas là pour faire des conversions mais juste dire au compilateur qu'on gère les types "à la main", ce qui n'est pas le cas ici.
Dans votre poste suivant, vous utilisez "std::stoi" et c'est bien mieux !!!
Elle sort d'où la variable "f" ???
Pourquoi vous emmerder avec des valeurs magiques comme "-100" ???
Pourquoi passer par des float/double (20.0 à la place de 20) ?
Si on passe par un champ "m_note_str" dans la classe Serie ou Cinema, le code dans le constructeur sera aussi simple que :
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 Cinema::setNote(std::wstring note) { m_note_str = std::to_wstring(20 * std::stoi(n)); } Cinema::Cinema(const path& racine):... m_note_str{L'(' + valuesColor + L"pas de note !" + keyColor + L')' + valuesColor}... { .... for (directory_iterator next(racine), end; next != end; ++next) { .... if(next.filename().compare(L"note.txt")==0) { std::vector<std::wstring> data = ::LoadDataFromFile(next); if(data.size()>0) { setNote(data[0]); } } .... } .... }Déjà indiqué que les cast, ça sert pas à cela.Marche pas !
wstr = std::to_wstring(static_cast<float>(Note / 20)); : ???
et ???
Que faire ?
Merci d'avance
Vous avez trouvé tout seul une bien meilleure méthode.
"D_I" comme nom de variable (globale ou de champ) ???
Non mais, vous déconnez !!! Donnez des noms correctes à vos variables !!!
Par exemple, vous avez un champ "m_episode" de type std::vector<Episode> qui contiendra les informations pour chaque épisode (Episode est une classe).
Pour faire la moyenne, le STL donne un ensemble d'algorithmes qui permet de faire ce calcul en une ligne à partir d'un std::vector.
Donc, en code, si un episode converti en float/double donne sa note :
@Mat.M, pourquoi fournir un code C (pas C++) qui date de plus de 30 ans ???
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 const std::wstring Serie::afficherNote() { double note = std::accumulate( m_episode.begin(), m_episode.end(), 0.0 )/ m_episode.size(); PrintTmp(std::to_wstring(note)); }
Toujours les mêmes problèmes de code trop compliqué.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 const void Cinema::afficher_Note(std::wstring& n_filename, std::wstring const& nomFichier) {...}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 const std::wstring Cinema::afficherNote() { PrintTmp(std::to_wstring(m_note)); }Non, un cast, c'est pas une conversion.Ok :
note = static_cast<int>(f * 20.0f);
Utilisez "std::stoi(...)" pour faire les conversions.
toute question mérite une réponse parce que ça marche très bien et que sur un projet qui comporte beaucoup de ligne de codes on ne peut pas trop pinailler non plus surtout s'il faut livrer à temps.@Mat.M, pourquoi fournir un code C (pas C++) qui date de plus de 30 ans ???
sinon pour Laurent_B je lui conseille vivement de passer par un SGBD via une interface comme ADO DB ou ODBC.
std::stoi(...), c'est quand même beaucoup beaucoup plus simple.et que sur un projet qui comporte beaucoup de ligne de codes on ne peut pas trop pinailler non plus surtout s'il faut livrer à temps.
Et ça fait un moment que je tanne @Laurent_B_ pour qu'il simplifie son code, en grande partie parce qu'il utilise des paradigmes du C et non du C++ (code retour, etc...) ou antédiluvien (trace avec des #define dans la console, etc...).
Oui, vrai !!! J'ai oublié tout !!! https://www.b-lolo.fr/avc/ : Accident Vasculaire Cérébral !!!Et ça fait un moment que je tanne @Laurent_B_ pour qu'il simplifie son code, en grande partie parce qu'il utilise des paradigmes du C et non du C++ (code retour, etc...) ou antédiluvien (trace avec des #define dans la console, etc...).
Avec Bacelar, mieux en mieux !!!
Bonsoir,
???
Fatigue !!!
Merci d'avance
On a déjà parlé du fait que la copie d'écran, c'est pas le top pour indiquer les messages d'erreur. cf. la fenêtre "Sortie" de Visual Studio.
Je crois que le compilateur gueule parce que vous avez déclaré une/des variables globales de nom "console" et qu'elle est défini nulle part.
Vous n'avez pas encore besoin de la classe Console, et encore moins d'une variable globale de ce type.
Dégagez rapidement toutes ces variables globales.
Mais dans l'immédiat, n'en rajoutez pas, SVP.
Bonjour,
Voilà : You 1.rar
Avec :
console.h/.cpp
you.cpp
Utils.cpp
Merci beaucoup
Bonsoir,
Merci de m'aidez
Ok : console.PrintStringW(console.hOut, ...);
serie.cpp, cinema.cpp et Utils.cpp
Exemple (pas ok) :
et (exemple)
Chaˉne d'origine : RTBFSolution ?
Merci d'avance
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager