PROBLÈME crosses initialization of 'std::ifstream

Résolu
charleslemagicien Messages postés 12 Date d'inscription mercredi 10 décembre 2008 Statut Membre Dernière intervention 16 août 2010 - 29 avril 2010 à 22:21
charleslemagicien Messages postés 12 Date d'inscription mercredi 10 décembre 2008 Statut Membre Dernière intervention 16 août 2010 - 30 avril 2010 à 00:07
Bonjour à tous,

J'ai un problème avec ma source j'utilise la fonction ifstream dans mon programme... Tout fonctionne à merveille par contre au moment de la compilation une erreur m'apparaît "crosses initialization of 'std::ifstream"...

Voici la source qui cause problème:

// premier ifstream

ifstream Account_GetID;

Account_GetID.open(String_DATA, ios::in);

if(Account_GetID)
{

string PWDString;

Account_GetID >> PWDString;
Account_GetID.close();

// deuxieme ifstream

ifstream LoginCheck;

LoginCheck.open(String_login, ios::in);

if(LoginCheck)
{

string LoginPWDString;

LoginCheck >> LoginPWDString;
LoginCheck.close();

// ==========END===

Voilà je ne comprend pas pourquoi ses deux ifstream entre en conflit pourtant il me semble bien définit du moins à mon avis mais le compilateur n'est pas d'accord...

dernier détail si je fais compiler ma source avec seulement une des deux fonctions ifstream sa marche nickel !

Quelqu'un peut-il m'éclairer

Merci d'avance

7 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
29 avril 2010 à 23:56
Oula, ça pique au yeux !
Effectivement tu as fait du C. Mais le C++ est un langage différent.
J'ai du mal à comprendre pourquoi tu ne le fais pas en C ? Quelle intérêt as-tu à le faire en C++ ?
Pour que ce soit du C++ propre, il faudrait quasiment tout refaire.

Il y a aussi des trucs super horribles:
- Les gotos (les cas où un goto est utile est très très rare ! Quand on place un goto dans son code, il y a 99% de chance qu'il ne soit pas justifié).
- Mono-fonction: on découpe son code en petite fonction. Une fonction ne devrait pas excéder 25 lignes en moyenne (hors commentaire).
- FILE* => Tu devrais utiliser std::ofstream et std::ifstream
- char* => std::string et std::stringstream
- include windows/conio/time => inutile pour ce code, et tu casses la portabilité (je suis Linux, et ça se voit tout de suite). En retirant des includes inutile j'ai pu compiler.
- gets => fonction non standard, à éviter. Préférer std::cin de toute façon en C++.
- Bannir totalement les "using namespace std;", comme déjà expliqué.
- system: A bannir aussi, brise la portabilité.

Pour répondre techniquement à ta question:
Cette erreur est provoqué par les gotos. Chaque variable à une portée (un scope). Or tu définis un std::ifstream dans un scope sous l'égide d'une étiquette. Le compilateur ne considère pas que cette variable est isolée, donc sa destruction est effective au sortir de la fonction main. Et comme tu peux potentiellement revenir sur celle-ci alors qu'elle n'a théoriquement pas été détruite, le compilateur s'en rend compte et te dit que tu redéclares encore cette variable.
Pour éviter ceci, tu simules un scope à l'aide d'accolades.

Ex:

label:
std::ifstream pouet;
...
goto label;
...
label2:


Correction en:

label:
{
std::ifstream pouet;
...
goto label;
...
}
label2:
{
}


Bien évidemment, je te conseil de choisir un langage (C ou C++) et de l'utiliser correctement (on ne fais pas du C++ comme du C).

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
3
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
29 avril 2010 à 23:07
Ceci fonctionne parfaitement chez moi:
#include 
#include <fstream>

int main()
{
  std::string String_DATA("toto.txt");
  std::string String_login("pouet.txt");
  std::ifstream Account_GetID;

  Account_GetID.open(String_DATA.c_str(), std::ios::in);

  if (Account_GetID)
  {
    std::string PWDString;

    Account_GetID >> PWDString;
    Account_GetID.close();

    // deuxieme ifstream

    std::ifstream LoginCheck;

    LoginCheck.open(String_login.c_str(), std::ios::in);

    if (LoginCheck)
    {
      std::string LoginPWDString;
      LoginCheck >> LoginPWDString;
      LoginCheck.close();
    }
  }

  return 0;
}


J'ai compilé comme ceci:
g++ -W -Wall -Wabi -pedantic main.cc


PS: Évite les "using namespace", voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
0
charleslemagicien Messages postés 12 Date d'inscription mercredi 10 décembre 2008 Statut Membre Dernière intervention 16 août 2010
29 avril 2010 à 23:15
je vais tester ta solution par contre un petit problème se pose! le String_DATA et le String_Login sont construit de cette façon:

strcpy(String_DATA, "C:\\Windows\\DBAcess\\DATA\\Secure\");
strcat(String_DATA, DATAName);
strcat(String_DATA, ".sDATA");

strcpy(String_login, "C:\\Windows\\DBAcess\\User\");
strcat(String_login, LOGIN);
strcat(String_login, ".dbacess");

Donc si je déclare simplement ainsi ceci me cause problème !
std::string String_DATA;
std::string String_login;

Désolé de mon ignorance je suis habitué au C donc j'ai un peu de difficulté a adapter au C++
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
29 avril 2010 à 23:18
Tu gardes les:
* String_DATA
* String_login
sous forme de char* et tu vires juste les c_str().
Ex:
char* String_DATA = ...;
Account_GetID.open(String_DATA, std::ios::in);

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
29 avril 2010 à 23:21
Ou alors, je viens d'y penser, tu oublies les strcpy, inutile en C++.
Genre:
std::string String_DATA = "C:\\Windows\\DBAcess\\DATA\\Secure\" + DATAName + ".sDATA";
std::string String_login = "C:\\Windows\\DBAcess\\User\" + LOGIN + ".dbacess";


_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
0
charleslemagicien Messages postés 12 Date d'inscription mercredi 10 décembre 2008 Statut Membre Dernière intervention 16 août 2010
29 avril 2010 à 23:28
j'ai essayé tes multiples idées mais j'arrive toujours au même problème de "crosses initialization" je me dis que le problème viens peut-être d'ailleurs dans le code alors je t'affiche toute la source:


// ===Include=====================================================

#include <fstream>
#include <windows.h>
#include <winable.h>
#include <stdlib.h>
#include
#include <conio.h>
#include <time.h>
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <cstdio>

using namespace std;

// =================================================END Include===

int main(void)
{


int hashd5 = 0;

char Option [80];
char Option_1 [] = "1";
char Option_2 [] = "2";
char Option_3 [] = "3";
char LOGIN [80];
char DATAName [80];
char String_login [80];
char String_DATA [80];
char MasterKey [80];
char Value_MasterKey [] = "Clm89mk";


FILE *OPEN_File;


RESET_Key:

printf("Master Key:");
gets(MasterKey);
printf("\n\n");
if (strcmp (MasterKey, Value_MasterKey) == 0)
{
goto RESET_MenuOption;
}
else {
printf("Mauvaise Cle !\n\n");

goto RESET_Key;
}

RESET_MenuOption:

printf("Menu\n");
printf("==================================================\n");
printf("Mot de passe Utilisateur.......................(1)\n");
printf("Mot de passe Fichier DATA......................(2)\n");
printf("Quitter........................................(3)\n\n");

StartMenu:

printf("Votre choix:");
gets(Option);

if (strcmp (Option, Option_1) == 0)
{
goto Option_1_Check;
}
else if (strcmp (Option, Option_2) == 0)
{
goto Option_2_Check;
}
else if (strcmp(Option, Option_3) == 0)
{
exit(0);
}
else {
printf("choix invalide\n\n");

goto StartMenu;
}

Option_1_Check:

printf("\nNom d'utilisateur:");
gets(LOGIN);

strcpy(String_login, "C:\\Windows\\DBAcess\\User\");
strcat(String_login, LOGIN);
strcat(String_login, ".dbacess");

OPEN_File = fopen(String_login, "r");

if (OPEN_File == NULL)
{

printf("Cet utilisateur n'existe pas\n\n");

goto Option_1_Check;

}
else {
goto RecoveryLOGIN;
}

RecoveryLOGIN:

ifstream LoginCheck;

LoginCheck.open(String_login, ios::in);

if(LoginCheck)
{

string LoginPWDString;

LoginCheck >> LoginPWDString;
LoginCheck.close();


char *ConvertString_PwdID1;

ConvertString_PwdID1 = new char [LoginPWDString.size()+1];
strcpy (ConvertString_PwdID1, LoginPWDString.c_str());

for(hashd5 = 0; hashd5 < strlen(ConvertString_PwdID1); hashd5++){

ConvertString_PwdID1[hashd5] = ConvertString_PwdID1[hashd5] - 16;
}
printf("Le mot de passe de "%s" est: "%s"\n\n", LOGIN, ConvertString_PwdID1);
system("pause");
system("cls");
}

goto RESET_MenuOption;


// ===================================================

Option_2_Check:

printf("\nNom fichier DATA:");
gets(DATAName);

strcpy(String_DATA, "C:\\Windows\\DBAcess\\DATA\\Secure\");
strcat(String_DATA, DATAName);
strcat(String_DATA, ".sDATA");

OPEN_File = fopen(String_DATA, "r");

if (OPEN_File == NULL)
{

printf("Ce fichier DATA protege n'existe pas\n\n");

goto Option_2_Check;

}
else {
goto RecoveryDATA;
}

RecoveryDATA:

ifstream Account_GetID;
Account_GetID.open(String_DATA, ios::in);

if(Account_GetID)
{

string PWDString;

Account_GetID >> PWDString;
Account_GetID.close();


char *ConvertString_PwdID;

ConvertString_PwdID = new char [PWDString.size()+1];
strcpy (ConvertString_PwdID, PWDString.c_str());

for(hashd5 = 0; hashd5 < strlen(ConvertString_PwdID); hashd5++){

ConvertString_PwdID[hashd5] = ConvertString_PwdID[hashd5] - 16;
}
printf("Le mot de passe du fichier "%s" est: "%s"\n\n",DATAName, ConvertString_PwdID);
system("pause");
system("cls");
}
goto RESET_MenuOption;

return 0;
}
0
charleslemagicien Messages postés 12 Date d'inscription mercredi 10 décembre 2008 Statut Membre Dernière intervention 16 août 2010
30 avril 2010 à 00:07
Je suis bien d'accord que ma source est bordélique et mal conçu mais je dois te dire que j'ai appris sur le tas comme on dis j'ai découvert cette passion très jeune mais sans jamais avoir de réelle formation. Ce sont par contre des gens comme toi qui me font avancé et me donne le goût de m'investir sérieusement dans la programmation... Mais par ou commencer je ne le sais pas...


Bref, merci pour la solution sa fonction maintenant !
0
Rejoignez-nous