Probleme sscanf char[] et char* [Résolu]

Signaler
Messages postés
136
Date d'inscription
samedi 1 mai 2004
Statut
Membre
Dernière intervention
26 mai 2007
-
Messages postés
136
Date d'inscription
samedi 1 mai 2004
Statut
Membre
Dernière intervention
26 mai 2007
-
Bonjour,


J'ai un mechant bug que je n arrive vraiment pas a regler!

Voila j'ai une fonction qui li un fichier

            char couchelu[50];

           
    sscanf(chaine, "%d %s; %f, %f, %f, %f, %f",
&numlayer, &couchelu, &h, &p, &r,&g,&b);

               

                switch(numlayer)

                {

                    case 0:

           
           
LLayer[numlayer].SetLayer(couchelu,"Well",0,-h,p,r,g,b,1.0);

                        break;

                    case 1:

           
           
LLayer[numlayer].SetLayer(couchelu,"N Diff",0,-h,p,r,g,b,1.0);

                        break;

                    case 2:

           
           
LLayer[numlayer].SetLayer(couchelu,"P Diff",0,-h,p,r,g,b,1.0);

                        break;

                 }

et mon SetLayer est de la forme (c'est une fonction d'une classe)
SetLayer(char* _nom_cif, char* _nom_couche, float z, float h, float p, float r, float g, float b, float a)

    {

        this->nom_cif = _nom_cif;

        this->nom_couche = _nom_couche;

        this->num_quads=0;

        this->zstart = z;

        this->hauteur = h;

        this->penetration=p;

        this->h = h;

        this->color.set(r, g, b, a);

        this->visible=true;

        this->existe=true;

    }

Seulement c'est vraiment bizzare parceque d apres le
debug ce qu'il lis dans le fichier texte arrive bien dans SetLayer mais
il met n'importe quoi a "nom_cif" genre un truc comme "¬|/$" !!!!

Mais si par exemple apres mon sscanf je "pirate" mon couchelu en mettant un couchelu = "Coucou";

bien sur dans tous les cas ce sera coucou qui sera envoyé, mais
"Coucou" est cette fois bien enregitré dans mon "nom_cif " de ma classe!


Une idée de pourquoi et comment régler mon probleme?


Merci beaucoup pour votre aide, ca fait des heures que j'essaie toutes les solutions que je trouve!

19 réponses

Messages postés
136
Date d'inscription
samedi 1 mai 2004
Statut
Membre
Dernière intervention
26 mai 2007

Tu as tout a fait raison, j'ai trouvé la solution tout l heure et j allais la poster.

J'enregistre dans nom_cif l'adresse de couchelu, donc apres tous mes
elements pointe vers cette adresse donc la meme valeur pour tous!

Solution : dans le while declarer char* couchelu = new char[50];


et voila!


En tout cas merci a tous pour votre mobilisation ;)


jojo
Messages postés
2333
Date d'inscription
samedi 28 février 2004
Statut
Membre
Dernière intervention
26 juillet 2013
36
Salut :

Comme la variable couchelu est de type "char *" alors tu dois omettre le "&" dans la fonction sscanf.




sscanf(chaine, "%d %s; %f, %f, %f, %f, %f", &numlayer,


couchelu

, &h, &p, &r,&g,&b);



                              
            
                                           
Messages postés
136
Date d'inscription
samedi 1 mai 2004
Statut
Membre
Dernière intervention
26 mai 2007

Je te remercie, mais j'avais deja essayé!

et ca me fait toujours n importe quoi :

En fait si je met couchelu au lieu de &couchelu et que je declare avant mon couchelu en char[50] ca me fait n importe quoi!

et si je declare mon couchelu en char* la j'ai une erreur en entrant
dans le switch du type : "Unhandled exception in 3D_VISU.exe:
0XC0000005: Access Violation" !!! A chaque fois que j essaie un truc,
soit ca ecrit n importe quoi, soit j'ai cette erreur!
Messages postés
136
Date d'inscription
samedi 1 mai 2004
Statut
Membre
Dernière intervention
26 mai 2007

Je viens de reussir a ne pas que ca ecrive n importe quoi, mais un
autre probleme se passe,  tous mes objets LLayer[] ont comme
nom_cif le dernier lu dans le fichier! C extrement bizzare
Messages postés
2333
Date d'inscription
samedi 28 février 2004
Statut
Membre
Dernière intervention
26 juillet 2013
36
Salut :

Fais attention à l'allocation de la mémoire.
NE JAMAIS UTILISER UN POINTEUR NON INITIALISE.

Je te conseille de changer la façon avec laquelle tu lis tes variables.
Messages postés
2333
Date d'inscription
samedi 28 février 2004
Statut
Membre
Dernière intervention
26 juillet 2013
36
Salut :

peux tu fournir la structure de ton fichier.
Pour te proposer une façon plus efficace pour lire tes données.
Messages postés
2333
Date d'inscription
samedi 28 février 2004
Statut
Membre
Dernière intervention
26 juillet 2013
36
Salut :

En quel mode tu ouvres ton fichier? (mode texte ou mode binaire)

Vérifie le paramètre de "fopen".

En ce qui concerne la variable couchelu elle doit être utilisée sans "&" dans la fonction "sscanf"
Messages postés
136
Date d'inscription
samedi 1 mai 2004
Statut
Membre
Dernière intervention
26 mai 2007

ALors en fait le probleme est vraiment bizzare, voici mon code, tu
verra que a la fin de chaque boucle de mon while j'ecris dans un
fichier la valeur du LLayer qui a ete sauvé... ca me donne dans le
fichier exactement ce que je veux, c'est genial... mais a la fin de ma
lecture du fichier quand tout es fini, je fait une boucle passant tous
mes LLayer et en ecrivant danc chaque valeur lu dans un autre fichier
pour verifier et la j'ai pas ce que je veux.


Ci dessous mon code et le resultat de mes deux fichier, tu verra comme c'est bizarre!

void SetConfig(HWND hwndDlg)

{

    char nom[100];

    char* NomCharge;


    char NomCharge2[100];

    bool FoundConfig=false;

    int numlayer=-1;

    float h, r, g, b, p;

    SendMessage(GetDlgItem( hwndDlg , ID_SEL) , CB_GETLBTEXT,
(WPARAM)SendMessage(GetDlgItem( hwndDlg , ID_SEL), CB_GETCURSEL, 0, 0),
(LPARAM)nom);


    CString test_nom;


    test_nom = CString(nom);

    FILE *filein;

    char chaine[255];
   
filein = fopen("configs.3dconf", "rt");   
            // File To
Load World Data From

    if(filein != NULL)

    {       

        FoundConfig = false;

        while (fgets(chaine, 250, filein)
!= NULL) // On lit le fichier tant qu'on ne reçoit pas d'erreur (NULL)

        {

           

            if(FoundConfig==true)

            {

               

                //char* couchelu;

           
    sscanf(chaine, "%d %s; %f, %f, %f, %f, %f",
&numlayer, couchelu, &h, &p, &r,&g,&b);

               

                switch(numlayer)

                {

                    case 0:

           
           
LLayer[numlayer].SetLayer(couchelu,"Well",0,-h,p,r,g,b,1.0);

                        break;

                    case 1:

           
           
LLayer[numlayer].SetLayer(couchelu,"N Diff",0,-h,p,r,g,b,1.0);

                        break;

                    case 2:

           
           
LLayer[numlayer].SetLayer(couchelu,"P Diff",0,-h,p,r,g,b,1.0);

                        break;

                    case 3:

           
           
LLayer[numlayer].SetLayer(couchelu,"Poly 1",0,h,p,r,g,b,1.0);

                        break;

                    case 4:

           
           
LLayer[numlayer].SetLayer(couchelu,"Poly
2",LLayer[3].zstart+LLayer[3].h,h,p,r,g,b,1.0);

                        break;

                    case 5:

           
           
LLayer[numlayer].SetLayer(couchelu,"Cont",0,h,p,r,g,b,1.0);

                        break;

                    case 6:

           
           
LLayer[numlayer].SetLayer(couchelu,"Metal
1",LLayer[5].zstart+LLayer[5].h,h,p,r,g,b,1.0);

                        break;

                    case 7:

           
           
LLayer[numlayer].SetLayer(couchelu,"Via
1",LLayer[6].zstart+LLayer[6].h,h,p,r,g,b,1.0);

                        break;

                    case 8:

           
           
LLayer[numlayer].SetLayer(couchelu,"Metal
2",LLayer[7].zstart+LLayer[7].h,h,p,r,g,b,1.0);

                        break;

                    case 9:

           
           
LLayer[numlayer].SetLayer(couchelu,"Via
2",LLayer[8].zstart+LLayer[8].h,h,p,r,g,b,1.0);

                        break;

                    case 10:

           
           
LLayer[numlayer].SetLayer(couchelu,"Metal
3",LLayer[9].zstart+LLayer[9].h,h,p,r,g,b,1.0);

                        break;

                    case 11:

           
           
LLayer[numlayer].SetLayer(couchelu,"NPLUS",0,h,p,r,g,b,1.0);

                        break;

                    case 12:

           
           
LLayer[numlayer].SetLayer(couchelu,"PPLUS",0,h,p,r,g,b,1.0);

                        break;

                    case 13:

           
           
LLayer[4].zstart=LLayer[4].zstart+h;

                        break;

                }

           

               

            }


            if(CString(3,chaine)=="nom")

            {

                sscanf(chaine, "nom %s", &nom);

                if(CString(nom).CompareNoCase(test_nom))

                {

                    FoundConfig = true;

                    NomCharge = nom;

                }

                else

                    FoundConfig = false;

            }

           

            if(numlayer!=-1)

            {

                FILE *stream;

   

                stream=fopen("tes0.3dconf","a+");

           
    fprintf(stream,"nom %s
%s\n",LLayer[numlayer].nom_cif, LLayer[numlayer].nom_couche);

                fclose(stream);

                numlayer=-1;

            }

        }

    }

    sprintf (NomCharge2, "Config %s chargé avec succès ", NomCharge);

    SendMessage(hStatusBar, SB_SETTEXT, 0, (LONG)NomCharge2);

    ConfigLoaded = true;


    FILE *stream;

   

    stream=fopen("tes.3dconf","w");

    for(int t=0; t<12; t++)

    {

        fprintf(stream,"nom %s %s\n",LLayer[t].nom_cif, LLayer[t].nom_couche);

    }

    fclose(stream);

   

}



Fichier que je veux obtenir et que j'obtiens dans tes0.3dconf

nom NWELL; Well

nom ACTIVE; N Diff

nom ACTIVE; P Diff

nom POLY; Poly 1

nom CONT; Cont

nom METAL1; Metal 1

nom VIA1; Via 1

nom METAL2; Metal 2

nom PPLUS; PPLUS



Fichier que j'obiten dans tes.3dconf ... donc bizzarement remodifier par je ne sais pas quoi!

nom PPLUS; Well

nom PPLUS; N Diff

nom PPLUS; P Diff

nom PPLUS; Poly 1

nom ; ;

nom PPLUS; Cont

nom PPLUS; Metal 1

nom PPLUS; Via 1

nom PPLUS; Metal 2

nom ; ;

nom ; ;

nom ; ;
Messages postés
136
Date d'inscription
samedi 1 mai 2004
Statut
Membre
Dernière intervention
26 mai 2007

Au fait , c'est normal que les indices 4, 9, 10 et 11 soient "vide" dans tes.3dconf
Messages postés
2333
Date d'inscription
samedi 28 février 2004
Statut
Membre
Dernière intervention
26 juillet 2013
36
Salut :

Cher ami, je remarque que dans to code tu oublie de fermer la flux associé à la variable "
filein
".

Ajouter un fclose.
Messages postés
2333
Date d'inscription
samedi 28 février 2004
Statut
Membre
Dernière intervention
26 juillet 2013
36
Salut :

le fclose (filein) dois être ajouter avant la dernière boucle "for".

Ou tout simplement ajoute un "commit" avant la boucle "for" et vers la fin de ta procédure fais un fclose(filein)
Messages postés
2333
Date d'inscription
samedi 28 février 2004
Statut
Membre
Dernière intervention
26 juillet 2013
36
Salut :

Comment ça va maintenant?
Est ce que le bug persiste?
Messages postés
136
Date d'inscription
samedi 1 mai 2004
Statut
Membre
Dernière intervention
26 mai 2007

J'ai ajouté le close(filein) apres mon if(filein != NULL){ ...}


mais le bug persiste :(


J'ai une fenetre openGL ou j ecris egalement la valeur de
LLayer[0].nom_cif et me donne PPLUS au lieu de NWELL comme dans le
deuxieme fichier!
Messages postés
136
Date d'inscription
samedi 1 mai 2004
Statut
Membre
Dernière intervention
26 mai 2007

J'ai compris ce qu'il se passe, mais je sais pas comment
l'arranger,  amon avis a chaque fois que je fais appelle a
SetLayer() il me met les valeur que j'envoie a TOUS mes objets!

comment faire pour arranger ca? voici la definition de ma classe:

Je definie LLayer comme ca :
LAYER* LLayer = new LAYER[13]();


et voila ma classe

class LAYER       
           
            // Build our
LAYER Class

{

public:

    int num_quads;

    bool visible, existe;

    float hauteur, zstart, h, penetration;

    char* nom_cif;

    char* nom_couche;

    vec4 color;

    QUAD* quad;   


    LAYER()

    {

        this->num_quads=0;

        this->zstart = 3.0;

        this->hauteur = 2.0;

        this->h = 5.0;

        this->quad = new QUAD[50000];

        this->color.set(0, 0, 0, 1.0);

        this->visible=true;

        this->nom_cif = ";";

        this->nom_couche = ";";

    }


    SetLayer(char* _nom_cif, char* _nom_couche, float z, float h, float p, float r, float g, float b, float a)

    {

        this->nom_cif = couchelu;

        this->nom_couche = _nom_couche;

        this->num_quads=0;

        this->zstart = z;

        this->hauteur = h;

        this->penetration=p;

        this->h = h;

        this->color.set(r, g, b, a);

        this->visible=true;

        this->existe=true;

    }


    void AddValue(float _centrex, float _centrey, float _qwidth, float _qlenght)

    {


        this->quad[num_quads].vertex[0].x = _centrex - (_qlenght/2);

        this->quad[num_quads].vertex[0].y = _centrey + (_qwidth/2);


        this->quad[num_quads].vertex[1].x = _centrex + (_qlenght/2);

        this->quad[num_quads].vertex[1].y = _centrey + (_qwidth/2);


        this->quad[num_quads].vertex[2].x = _centrex + (_qlenght/2);

        this->quad[num_quads].vertex[2].y = _centrey - (_qwidth/2);

                   

        this->quad[num_quads].vertex[3].x = _centrex - (_qlenght/2);

        this->quad[num_quads].vertex[3].y = _centrey - (_qwidth/2);


        if(MinX>this->quad[num_quads].vertex[0].x)

            MinX=this->quad[num_quads].vertex[0].x;

        if(MaxX<this->quad[num_quads].vertex[1].x)

            MaxX=this->quad[num_quads].vertex[1].x;

        if(MinY>this->quad[num_quads].vertex[2].y)

            MinY=this->quad[num_quads].vertex[2].y;

        if(MaxY<this->quad[num_quads].vertex[0].y)

            MaxY=this->quad[num_quads].vertex[0].y;


        this->num_quads= this->num_quads+1;

    }


    ~LAYER()

    {

        delete this->quad;

        this->quad = new QUAD[50000];

    }

   

};
Messages postés
2333
Date d'inscription
samedi 28 février 2004
Statut
Membre
Dernière intervention
26 juillet 2013
36
Salut :

Pourquoi ne pas créer un accesseur (méthode) pour chaque attribut?
Messages postés
136
Date d'inscription
samedi 1 mai 2004
Statut
Membre
Dernière intervention
26 mai 2007

C'est a dire?

genre au lieu de faire un LAYER[13] j'en fait 13 de nom different : LAYER layer1, LAYER layer2 ,... ?
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
15
Ok je vais émettre une hypothèse, hypothèse car je ne connais pas très bien les classes.

this->nom_cif = couchelu;

Ok. nom_cif est un pointeur char (char*) donc quand tu fais ça, tu te trouve simplement à tranférer le pointeur. Cependant, couchelu est dans une fonction non? Si oui, c'est une variable locale. Quand ta fonction est terminé, cette variable est détruite donc le pointeur nom_cif qui pointait sur couchelu est désormait invalide.

C'est une hypothèse car, comme je disais, je ne connais pas bien les classes, mais ce pourrais expliquer le problème.

C++ (@++)<!--
Messages postés
136
Date d'inscription
samedi 1 mai 2004
Statut
Membre
Dernière intervention
26 mai 2007

Désolé j'ai oublié de préciser que couchelu je l'ai déclaré globale (donc en extern) en test!

mais ca fait la meme chose si on met this->nom_cif = _nom_cif ;

Comment faire pour que ma fonction SetLayer n'agisse que sur l'element
n de mon LLayer[n] et non sur tout les elements de mon tableau de layer
LLayer[]!!!

Mais le pire, c'est que c'est uniquement le champs nom_cif qui est modifié partout!!!!! pourquoi!?
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
15
nom_cif est un pointeur et comme son nom le dit, il pointe vers une adresse. Un pointeur n'enregistre rien, ce n'est qu'une adresse. Donc si tu pointe vers couchelu, il prendra simplement l'adresse de couchelu. Mais si tu modifie la chaine contenue par couchelu, les pointeurs nom_cif n'enregisteront pas l'ex-chaine. Ils continuront de pointer sur couchelu qui est modifié.

Bon alors, c'est encore une hypothèse car je le redit, je ne connais pas bien les classes (on sais jamais) mais logiquement, c'est ce qui devrais ce passer.

C++ (@++)<!--