Pour le problème de retour, je parlais de fopen() : À moins que tu veuilles dire que fopen() crashait directement ?
Pour le crash de new: Un débordement de buffer, un dépassement de tableau, l'erreur classique quoi. Poste ton code.
Pour le problème de retour, je parlais de fopen() : À moins que tu veuilles dire que fopen() crashait directement ?
Pour le crash de new: Un débordement de buffer, un dépassement de tableau, l'erreur classique quoi. Poste ton code.
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Oui fopen() plante directement.
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 void GetSoft(char *fileName) { string NomPc; HKEY hkKey; HKEY hkKeyOpened; char *subKey; //cout << 2 << endl; subKey = new char[2048]; //cout << 3 << endl; DWORD dwName = 2048 * sizeof(TCHAR); int xSubKey = 0; int xSubKeyReal = 0; char *testConst; char *testConst2; ofstream fichierRetour(fileName, ios::out | ios::app); if (RegConnectRegistry(NomPc.c_str(),HKEY_LOCAL_MACHINE,&hkKey) == ERROR_SUCCESS) { RegOpenKeyEx(hkKey, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\", 0, KEY_ALL_ACCESS, &hkKeyOpened); while(RegEnumKey(hkKeyOpened, xSubKey, subKey, dwName)!= ERROR_NO_MORE_ITEMS) { testConst = strstr (subKey,"{"); testConst2 = strstr (subKey,"KB"); if(testConst == NULL && testConst2 == NULL) { xSubKeyReal++; fichierRetour << subKey << endl; } testConst = NULL; xSubKey++; } fichierRetour << "--------------------------------------------" << endl; fichierRetour << "Softs : " << xSubKeyReal << endl; fichierRetour.close(); } delete subKey; }
Pour ceux qui aime quand ça coupe : http://lcdd.stass.eu
Je dirais plutôt par malchance.Envoyé par Mongaulois
Verbalinsurection: si cette fonction plante avant même le ofstream, on ne peut pas vraiment dire que "ça marche avec ofstream" : Ça plantera tout autant avec ofstream qu'avec fopen().
Tu devrais poster ton code d'avant GetSoft(). Et ton fileName devrait être un const char * ou char const *.
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Quand j'ai remplacé fopen() par ofstream tout a bien marché sous vista. const char *, pourquoi? (désolé j'aime bien comprendre, normal...)
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 char *recupInfo() { string NomPc; char ucName[64], userName[64]; char *constructeur; constructeur = new char; char *model; model = new char; char *cpu; cpu = new char; int ram; char *osVersion; osVersion = new char; char *fileName; fileName = new char; DWORD d; osVersion = GetOSVersion(); d = 64; GetUserName(userName, &d); d = 64; GetComputerName(ucName, &d); constructeur = GetConstructeur(); model = GetModel(); cpu = GetCpu(); ram = GetRam(); char szthis[300]; char* c = szthis + GetModuleFileName(0, szthis, 300); while(*c != '\\') c--; *c = 0; sprintf(fileName, "%s\\%s.gps", szthis, ucName); ofstream fichierRetour(fileName, ios::out | ios::trunc); fichierRetour << "--------------------------------------------" << endl; fichierRetour << " StasS© - L***" << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << " Gest-Parc Scanner" << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << "Machine : " << ucName << endl; fichierRetour << "Utilisateur : " << userName << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << "Constructeur : " << constructeur << endl; fichierRetour << "Model : " << model << endl; fichierRetour << "Version de l'OS : " << osVersion << endl; fichierRetour << "CPU : " << cpu << endl; fichierRetour << "RAM : " << ram << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour.close(); GetSoft(fileName); delete constructeur; delete model; delete cpu; delete osVersion; return fileName; }
Pour ceux qui aime quand ça coupe : http://lcdd.stass.eu
Ouille...
C'est un bordel sans nom. Tu fais des allocations dynamiques inutiles, utilises beaucoup de char* ce qui est déconseillé en C++ (on dirait du C, mais ça pourrait aussi bien être du mauvais C).
Je vais faire quelques commentaires sur ton code.
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Ok merci pour tout medinoc, j'attend tes conseils avec impatience...
Pour ceux qui aime quand ça coupe : http://lcdd.stass.eu
Et voilà, j'ai trouvé l'erreur!
Tu ne sais visiblement pas te servir des char* correctement. Aussi, tu devrais te limiter aux tableaux de char, aux std::string et aux std::ostringstream.
Voici le code avec une correction légère des allocations inutiles et du bug du sprintf().
Une correction plus complète serait de remplacer complètement le sprintf() par l'utilisation d'un ostringstream.
Code C++ : 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 #include <windows.h> #include <string> #include <fstream> using namespace std; //Pour que ça compile char * GetOSVersion(); char * GetConstructeur(); char * GetModel(); char * GetCpu(); int GetRam(); char * GetSoft(char const *); char *recupInfo() { string NomPc; char ucName[64] = "", userName[64] = ""; //Pourquoi allouer un char à chaque fois, d'autant que tu "oublies" leur pointeur ? char *constructeur = NULL; char *model = NULL; char *cpu = NULL; int ram; char *osVersion = NULL; char *fileName = NULL; //Ce code récupère nom d'ordi et d'utilisateur, //mais se moque de ce qui arrive en cas d'échec de GetUserName() ou GetComputerName() { DWORD d; d = 64; GetUserName(userName, &d); d = 64; GetComputerName(ucName, &d); //Précaution: On s'assure que le buffer est terminé par un caractère nul, //Que la fonction ait réussi ou non. userName[64-1] = '\0'; ucName[64-1] = '\0'; } ram = GetRam(); //Je n'ai aucune confiance dans ces fonctions: S'il y a un débordement dedans, //ça peut te pourrir le programme suffisamment pour que fopen() ou un new plante. osVersion = GetOSVersion(); constructeur = GetConstructeur(); model = GetModel(); cpu = GetCpu(); char szthis[300]; int len = GetModuleFileName(0, szthis, 300); if(len==300) { //Erreur: Le chemin est trop grand pour tenir dans szthis //On utilise delete[] pour les tableaux, pas delete delete[] constructeur; delete[] model; delete[] cpu; delete[] osVersion; return NULL; } char* pEnd = szthis + len; while(*pEnd != '\\') pEnd--; *pEnd = '\0'; /* PAF! L'ERREUR EST ICI: Dans ton code, fileName a une taille de un seul char, pas plus. Dans le code corrigé, il n'est même pas alloué. */ //<Correction> //Taille totale = szthis + '\\' + ucName + ".gpc" + \0 terminal. fileName = new char[strlen(szthis) + 1 + strlen(ucName) + 4 + 1]; //</correction> sprintf(fileName, "%s\\%s.gps", szthis, ucName); ofstream fichierRetour(fileName, ios::out | ios::trunc); fichierRetour << "--------------------------------------------" << endl; fichierRetour << " StasS© - L***" << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << " Gest-Parc Scanner" << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << "Machine : " << ucName << endl; fichierRetour << "Utilisateur : " << userName << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << "Constructeur : " << constructeur << endl; fichierRetour << "Model : " << model << endl; fichierRetour << "Version de l'OS : " << osVersion << endl; fichierRetour << "CPU : " << cpu << endl; fichierRetour << "RAM : " << ram << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour.close(); GetSoft(fileName); //On utilise delete[] pour les tableaux, pas delete delete[] constructeur; delete[] model; delete[] cpu; delete[] osVersion; return fileName; }
Quand tu auras le temps, il serait bien ensuite de remplacer toutes tes fonctions retournant des char* par des fonctions qui retournent des strings...
NOTE: Ce code ne compilera pas si tu ne remplaces pas char* par const char * dans le prototype de ta fonction GetSoft(), car string::c_str() retourne un const char *.
Code C++ : 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 #include <windows.h> #include <string> #include <fstream> #include <sstream> using namespace std; //Med: Remplacer tout ça par des retours de std::string quand tu auras le temps. //Pour que ça compile char * GetOSVersion(); char * GetConstructeur(); char * GetModel(); char * GetCpu(); int GetRam(); char * GetSoft(char const *); string recupInfo() { char ucName[64] = "", userName[64] = ""; //Pourquoi allouer un char à chaque fois, d'autant que tu "oublies" leur pointeur ? char *constructeur = NULL; char *model = NULL; char *cpu = NULL; int ram; char *osVersion = NULL; string fileName; //Ce code récupère nom d'ordi et d'utilisateur, //mais se moque de ce qui arrive en cas d'échec de GetUserName() ou GetComputerName() { DWORD d; d = 64; GetUserName(userName, &d); d = 64; GetComputerName(ucName, &d); //Précaution: On s'assure que le buffer est terminé par un caractère nul, //Que la fonction ait réussi ou non. userName[64-1] = '\0'; ucName[64-1] = '\0'; } ram = GetRam(); //Je n'ai aucune confiance dans ces fonctions: S'il y a un débordement dedans, //ça peut te pourrir le programme suffisamment pour que fopen() ou un new plante. osVersion = GetOSVersion(); constructeur = GetConstructeur(); model = GetModel(); cpu = GetCpu(); char szthis[300]; int len = GetModuleFileName(0, szthis, 300); if(len==300) { //Erreur: Le chemin est trop grand pour tenir dans szthis //On utilise delete[] pour les tableaux, pas delete delete[] constructeur; delete[] model; delete[] cpu; delete[] osVersion; return NULL; } char* pEnd = szthis + len; while(*pEnd != '\\') pEnd--; *pEnd = '\0'; { ostringstream oss; oss << szthis << '\\' << ucName << ".gpc"; fileName = oss.str(); } ofstream fichierRetour(fileName.c_str(), ios::out | ios::trunc); fichierRetour << "--------------------------------------------" << endl; fichierRetour << " StasS© - L***" << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << " Gest-Parc Scanner" << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << "Machine : " << ucName << endl; fichierRetour << "Utilisateur : " << userName << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << "Constructeur : " << constructeur << endl; fichierRetour << "Model : " << model << endl; fichierRetour << "Version de l'OS : " << osVersion << endl; fichierRetour << "CPU : " << cpu << endl; fichierRetour << "RAM : " << ram << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour.close(); GetSoft(fileName.c_str()); //On utilise delete[] pour les tableaux, pas delete delete[] constructeur; delete[] model; delete[] cpu; delete[] osVersion; return fileName; }
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Ok merci beaucoup pour tout ça medinoc.
Je regarde ça dans la journée, je fais toutes les corrections possible.
Je te posterais le code pour que tu me dise...
Merci encore !
Pour ceux qui aime quand ça coupe : http://lcdd.stass.eu
Voila mon code maintenant :
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 string recupInfo() { string NomPc; char ucName[64] = "", userName[64] = ""; string constructeur; string model; string cpu; int ram; string osVersion; string fileName; DWORD d; osVersion = GetOSVersion(); d = 64; GetUserName(userName, &d); d = 64; GetComputerName(ucName, &d); constructeur = GetConstructeur(); model = GetModel(); cpu = GetCpu(); ram = GetRam(); char szthis[300]; char* c = szthis + GetModuleFileName(0, szthis, 300); while(*c != '\\') c--; *c = 0; ostringstream oss; oss << szthis << '\\' << ucName << ".gps"; fileName = oss.str(); ofstream fichierRetour(fileName.c_str(), ios::out | ios::trunc); fichierRetour << "--------------------------------------------" << endl; fichierRetour << " StasS© - L****" << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << " Gest-Parc Scanner" << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << "Machine : " << ucName << endl; fichierRetour << "Utilisateur : " << userName << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << "Constructeur : " << constructeur << endl; fichierRetour << "Model : " << model << endl; fichierRetour << "Version de l'OS : " << osVersion << endl; fichierRetour << "CPU : " << cpu << endl; fichierRetour << "RAM : " << ram << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour.close(); GetSoft(fileName.c_str()); return fileName; }Tu en pense quoi?
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 void GetSoft(const char *fileName) { string NomPc; HKEY hkKey; HKEY hkKeyOpened; char *subKey; //cout << 2 << endl; subKey = new char[2048]; //cout << 3 << endl; DWORD dwName = 2048 * sizeof(TCHAR); int xSubKey = 0; int xSubKeyReal = 0; char *testConst; char *testConst2; ofstream fichierRetour(fileName, ios::out | ios::app); if (RegConnectRegistry(NomPc.c_str(),HKEY_LOCAL_MACHINE,&hkKey) == ERROR_SUCCESS) { RegOpenKeyEx(hkKey, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\", 0, KEY_ALL_ACCESS, &hkKeyOpened); while(RegEnumKey(hkKeyOpened, xSubKey, subKey, dwName)!= ERROR_NO_MORE_ITEMS) { testConst = strstr (subKey,"{"); testConst2 = strstr (subKey,"KB"); if(testConst == NULL && testConst2 == NULL) { xSubKeyReal++; fichierRetour << subKey << endl; } testConst = NULL; xSubKey++; } fichierRetour << "--------------------------------------------" << endl; fichierRetour << "Softs : " << xSubKeyReal << endl; fichierRetour.close(); } delete subKey; }
Je connaissais pas "sstream" ça l'ai pratiqueMais à quoi servent les 2 { } ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 { ostringstream oss; oss << szthis << '\\' << ucName << ".gpc"; fileName = oss.str(); }
J'essaie, j'essaie, j'apprend, j'apprend, un jour je saurais...
Pour ceux qui aime quand ça coupe : http://lcdd.stass.eu
C'est pas mal, mais tu devrais remettre les deux lignes supplémentaires que j'avais ajouté pour userName et ucName : Ce sont des précautions.
Pour les mêmes raisons, tu devrais remettre mes corrections pour GetModuleFileName().
Les accolades sans if ni for ni rien servent à limiter la portée des variables: J'avais limité la portée de d parce qu'on n'en avait plus besoin après, et j'ai fait la même chose pour le ostringstream : Une fois sorti du bloc d'accolade, le ostringstream n'existait plus.
C'est une pratique à prendre, et c'est encore plus important en C où l'on ne peut déclarer des variables qu'en début de bloc.
Dans ta fonction GetSoft, tu dois rester cohérent entre subKey et dwName: Si subkey est de type char*, utilise sizeof(char). Si subKey est de type TCHAR*, utilise sizeof(TCHAR).
Le plus simple est de laisser le compilo s'en occuper ainsi:
Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part DWORD dwName = 2048 * sizeof(*subKey);
Et pour libérer subKey, tu dois utiliser delete[] et non pas delete.
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Merci pour tes explications Médinoc, voici le resultat :
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 string recupInfo() { string NomPc; char ucName[64] = "", userName[64] = ""; string constructeur; string model; string cpu; int ram; string osVersion; string fileName; { DWORD d; d = 64; GetUserName(userName, &d); d = 64; GetComputerName(ucName, &d); userName[64-1] = '\0'; ucName[64-1] = '\0'; } osVersion = GetOSVersion(); constructeur = GetConstructeur(); model = GetModel(); cpu = GetCpu(); ram = GetRam(); char szthis[300]; int len = GetModuleFileName(0, szthis, 300); if(len==300) { return NULL; } char* pEnd = szthis + len; while(*pEnd != '\\') pEnd--; *pEnd = '\0'; ostringstream oss; oss << szthis << '\\' << ucName << ".gps"; fileName = oss.str(); ofstream fichierRetour(fileName.c_str(), ios::out | ios::trunc); fichierRetour << "--------------------------------------------" << endl; fichierRetour << " StasS© - L***" << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << " Gest-Parc Scanner" << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << "Machine : " << ucName << endl; fichierRetour << "Utilisateur : " << userName << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour << "Constructeur : " << constructeur << endl; fichierRetour << "Model : " << model << endl; fichierRetour << "Version de l'OS : " << osVersion << endl; fichierRetour << "CPU : " << cpu << endl; fichierRetour << "RAM : " << ram << endl; fichierRetour << "--------------------------------------------" << endl; fichierRetour.close(); GetSoft(fileName.c_str()); return fileName; }
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 void GetSoft(const char *fileName) { string NomPc; HKEY hkKey; HKEY hkKeyOpened; char *subKey; subKey = new char[2048]; DWORD dwName = 2048 * sizeof(*subKey); int xSubKey = 0; int xSubKeyReal = 0; char *testConst; char *testConst2; ofstream fichierRetour(fileName, ios::out | ios::app); if (RegConnectRegistry(NomPc.c_str(),HKEY_LOCAL_MACHINE,&hkKey) == ERROR_SUCCESS) { RegOpenKeyEx(hkKey, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\", 0, KEY_ALL_ACCESS, &hkKeyOpened); while(RegEnumKey(hkKeyOpened, xSubKey, subKey, dwName)!= ERROR_NO_MORE_ITEMS) { testConst = strstr (subKey,"{"); testConst2 = strstr (subKey,"KB"); if(testConst == NULL && testConst2 == NULL) { xSubKeyReal++; fichierRetour << subKey << endl; } testConst = NULL; xSubKey++; } fichierRetour << "--------------------------------------------" << endl; fichierRetour << "Softs : " << xSubKeyReal << endl; fichierRetour.close(); } delete[] subKey; }
Pour ceux qui aime quand ça coupe : http://lcdd.stass.eu
recupInfo() me parait OK
GetSoft() est pas mal, mais il manque encore des tests, et il peut être encore mieux en réduisant la portée de certaines variables:
Ici, j'ai réduit la portée de hkKeyOpened et des deux char*.
Code C++ : 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 void GetSoft(const char *fileName) { //Attention, NomPc n'est pas rempli: Il ne contient rien pour l'instant string NomPc; HKEY hkKey; char *subKey = new char[2048]; DWORD dwName = 2048 * sizeof(*subKey); int xSubKey = 0; int xSubKeyReal = 0; ofstream fichierRetour(fileName, ios::out | ios::app); if (RegConnectRegistry(NomPc.c_str(),HKEY_LOCAL_MACHINE,&hkKey) == ERROR_SUCCESS) { HKEY hkKeyOpened = NULL; //Le while bouclera indéfiniement si l'ouverture échoue et qu'on ne teste pas. //Donc, on teste. //Et aussi, on ne demande plus KEY_ALL_ACCESS puisqu'on ne fait que de la lecture. if(RegOpenKeyEx(hkKey, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\", 0, KEY_READ, &hkKeyOpened) == ERROR_SUCCESS) { while(RegEnumKey(hkKeyOpened, xSubKey, subKey, dwName)!= ERROR_NO_MORE_ITEMS) { char * testConst = strstr (subKey,"{"); char * testConst2 = strstr (subKey,"KB"); if(testConst == NULL && testConst2 == NULL) { xSubKeyReal++; fichierRetour << subKey << endl; } testConst = NULL; xSubKey++; } fichierRetour << "--------------------------------------------" << endl; fichierRetour << "Softs : " << xSubKeyReal << endl; fichierRetour.close(); //Attention, tu avais oublié RegCloseKey() RegCloseKey(hkKeyOpened); } } //Attention, tu avais oublié RegCloseKey() RegCloseKey(hkKey); delete[] subKey; }
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Merci pour tout Médinoc (euh...je me répéte là????) ba ouai mais il faut bien que je le dise. J4ai suivi tes conseils et en même temps je comprends un peu plus la portée des variables et comment résoudre certains de mes soucis.
Peut tu m'eclairer un peu sur 2 choses encore?
- Comment savoir si je dois faire un char *, char, string? (peut etre bete comme question mais ....) j'ai un peu de mal à comprendre pourquoi allocation dynamique ou pas et ce que ça siignifie exactement...
- Dans une fonction, si tu as une declaration type char *[...] new char; pour le delete, comment fais tu puisque ta fonction s'arrete avec le return...(encore une question bete??)
Pour ceux qui aime quand ça coupe : http://lcdd.stass.eu
De rien
- Pour tout cela, je dirais:
- string tant que c'est possible
- tableau de char si tu as besoin d'un pointeur non-const, que tu connais la taille à la compilation et qu'elle est petite.
- char* + new[] si tu as besoin d'un pointeur non-const, mais la taille est grande ou inconnue à la compilation.
- Sachant que je considère généralement 2048 comme "grand" pour les chars, c'est pourquoi j'ai laissé l'allocation dynamique.
- Pour l'allocation dynamique directe, je vois deux cas:
- soit le pointeur ne doit pas être retourné, auquel cas il faut faire le delete[] avant le return
- soit le pointeur est retourné, auquel cas c'est la fonction appelante qui doit faire le delete[].
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Je ne vois qu'un seule chose à dire, merci monsieur Médinoc
Je pense que je vais continuer comme ça, certainement que je reviendrai poster mon code pour voir si je retiens bien la leçon
A tres bientot et bonne continuation à toi mais aussi à tous ceux qui ont participer à ce thread!
Pour ceux qui aime quand ça coupe : http://lcdd.stass.eu
D'après le code posté j'ai l'impression que tu programmes en Java et que tu souhaites apprendre le C/C++ je me trompe ?
Contrairement à Java on fait rarement variable=new typeVariable il suffit de la déclarer dans une fonction.
Les new c'est pour une déclaration dynamique de tableaux de variables.
Ma théorie est sans doute fausse mais il est préférable d'utiliser CreateFile.
Pour ceux qui aime quand ça coupe : http://lcdd.stass.eu
Erf encore un problème...
Je rouvre pas de thread pour pas trop encombrer sinon on ne verrai plus que moi :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 int main() { int time; int port; char addIp; lectureIni(&time, &port, &addIp); }La fonction c_inifile_get_string() retourne un char *.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 void lectureIni(int *time, int *port, char *addIp) { c_inifile_init("gps.ini", NULL); { char *timeTmp = c_inifile_get_string("Gest-Parser Scanner", "Time", NULL); *time = atoi(timeTmp); char *portTmp = c_inifile_get_string("Server", "Port", NULL); *port = atoi(portTmp); *addIp = c_inifile_get_string("Server", "IP", NULL); } c_inifile_close(); }
Le code coimpile jusqu'àet me donne comme erreure:
Code : Sélectionner tout - Visualiser dans une fenêtre à part *addIp = c_inifile_get_string("Server", "IP", NULL);Merci!error: invalid conversion from `char*' to `char'
Pour ceux qui aime quand ça coupe : http://lcdd.stass.eu
Utilise un char ** en paramètre de ta fonction lectureIni()
De plus, vérifie que timeTmp et portTmp n'ont pas besoin d'être libérés (free(), tu sais). Je ne connais pas c_inifile...
Et au passage, atoi() est déprécié au profit de strtol() dont la gestion d'erreur est meilleure.
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
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