Probleme sscanf char[] et char*

Résolu
jojomillenium Messages postés 136 Date d'inscription samedi 1 mai 2004 Statut Membre Dernière intervention 26 mai 2007 - 26 oct. 2006 à 19:16
jojomillenium Messages postés 136 Date d'inscription samedi 1 mai 2004 Statut Membre Dernière intervention 26 mai 2007 - 27 oct. 2006 à 16:26
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

jojomillenium Messages postés 136 Date d'inscription samedi 1 mai 2004 Statut Membre Dernière intervention 26 mai 2007
27 oct. 2006 à 16:26
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
3
Ombitious_Developper Messages postés 2333 Date d'inscription samedi 28 février 2004 Statut Membre Dernière intervention 26 juillet 2013 38
26 oct. 2006 à 20:33
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);



                              
            
                                           
0
jojomillenium Messages postés 136 Date d'inscription samedi 1 mai 2004 Statut Membre Dernière intervention 26 mai 2007
26 oct. 2006 à 20:43
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!
0
jojomillenium Messages postés 136 Date d'inscription samedi 1 mai 2004 Statut Membre Dernière intervention 26 mai 2007
26 oct. 2006 à 20:55
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
0

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

Posez votre question
Ombitious_Developper Messages postés 2333 Date d'inscription samedi 28 février 2004 Statut Membre Dernière intervention 26 juillet 2013 38
26 oct. 2006 à 20:58
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.
0
Ombitious_Developper Messages postés 2333 Date d'inscription samedi 28 février 2004 Statut Membre Dernière intervention 26 juillet 2013 38
26 oct. 2006 à 21:01
Salut :

peux tu fournir la structure de ton fichier.
Pour te proposer une façon plus efficace pour lire tes données.
0
Ombitious_Developper Messages postés 2333 Date d'inscription samedi 28 février 2004 Statut Membre Dernière intervention 26 juillet 2013 38
26 oct. 2006 à 21:04
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"
0
jojomillenium Messages postés 136 Date d'inscription samedi 1 mai 2004 Statut Membre Dernière intervention 26 mai 2007
26 oct. 2006 à 21:06
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 ; ;
0
jojomillenium Messages postés 136 Date d'inscription samedi 1 mai 2004 Statut Membre Dernière intervention 26 mai 2007
26 oct. 2006 à 21:09
Au fait , c'est normal que les indices 4, 9, 10 et 11 soient "vide" dans tes.3dconf
0
Ombitious_Developper Messages postés 2333 Date d'inscription samedi 28 février 2004 Statut Membre Dernière intervention 26 juillet 2013 38
26 oct. 2006 à 21:21
Salut :

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

Ajouter un fclose.
0
Ombitious_Developper Messages postés 2333 Date d'inscription samedi 28 février 2004 Statut Membre Dernière intervention 26 juillet 2013 38
26 oct. 2006 à 21:23
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)
0
Ombitious_Developper Messages postés 2333 Date d'inscription samedi 28 février 2004 Statut Membre Dernière intervention 26 juillet 2013 38
26 oct. 2006 à 22:25
Salut :

Comment ça va maintenant?
Est ce que le bug persiste?
0
jojomillenium Messages postés 136 Date d'inscription samedi 1 mai 2004 Statut Membre Dernière intervention 26 mai 2007
26 oct. 2006 à 22:53
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!
0
jojomillenium Messages postés 136 Date d'inscription samedi 1 mai 2004 Statut Membre Dernière intervention 26 mai 2007
26 oct. 2006 à 23:31
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];

    }

   

};
0
Ombitious_Developper Messages postés 2333 Date d'inscription samedi 28 février 2004 Statut Membre Dernière intervention 26 juillet 2013 38
26 oct. 2006 à 23:40
Salut :

Pourquoi ne pas créer un accesseur (méthode) pour chaque attribut?
0
jojomillenium Messages postés 136 Date d'inscription samedi 1 mai 2004 Statut Membre Dernière intervention 26 mai 2007
26 oct. 2006 à 23:58
C'est a dire?

genre au lieu de faire un LAYER[13] j'en fait 13 de nom different : LAYER layer1, LAYER layer2 ,... ?
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
27 oct. 2006 à 00:13
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++ (@++)<!--
0
jojomillenium Messages postés 136 Date d'inscription samedi 1 mai 2004 Statut Membre Dernière intervention 26 mai 2007
27 oct. 2006 à 07:43
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!?
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
27 oct. 2006 à 15:28
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++ (@++)<!--
0
Rejoignez-nous