IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Comparaison dans une lecture binaire (cas particulier)


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut Comparaison dans une lecture binaire (cas particulier)
    Salut à tous,

    Dans le cadre d'une importation de fichier propriétaire, je dois lire en mode binaire puis tester les valeurs pour savoir ou je me trouve dans la structure de celui ci (il est organisé en "chunks").

    Alors j'ai un code source qui fait cette importation, mais j'aurais souhaité le refaire pour déja m'améliorer mais également changer le mode d'acces (il passe par des memcpy...)

    Donc vaillant gaillard que je suis, je fais mes recherches, determine qu'apparement, au vu des topics du forums et de la FAQ il faut passer par ifstream.

    Donc je balance un petit bout de code pour voir si au moins j'arrive à lire le premier noeud composé comme suit :

    ID : 2 octets
    longueur_chunk : 4 octets.

    voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #define MAIN_3DS 0x4d4d
    unsigned char buff;       //buffer de lecture
    ifstream filein(filename.c_str(),ios::binary);    //ouverture du fichier
    if(filein)    // si l'ouverture a réussi
    {
    filein.read(reinterpret_cast<char*>(&buff),2);    //on lit les deux premiers octets -> Id
    if(buff==MAIN_3DS)
    printf("reussi");
    filein.read(reinterpret_cast<char*>(&buff),4);    //on lit les 4 octets suivants
    }
    filein.close();
    Donc voici mes deux questions :

    1) filein.read deplace bien le curseur ? c'est à dire qu'apres un read de 2 octets, le prochain read commencera au troisieme ? (je prefere etre sur car j'ai un petit doute)

    2) Mon test ne fonctionne pas...
    Si je fais afficher le contenu de mon buff, il m'affiche "M", je suppose qu'il faut que je fasse quelque chose à ce buff pour pouvoir le tester avec la valeur de ma constante non ?Comment faire pour que ça passe ? Sincerement, je ne vois pas trop comment faire là.

    Merci d'avance et désolé pour la récurrence du sujet ^^ apparement c'est un probleme mystique qui touche pas mal de monde
    @++

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    1) Oui

    2) Tu ne pourras jamais mettre 2 ou 4 octets dans un unsigned char... Tu peux créer un tableau de N char, ou directement utiliser des types ayant la bonne taille, pour peu que tu sois sûr de ceux-ci selon ton système.

    Tu peux aussi regarder comment font les autres chargeurs de 3DS, il y en a pas mal en open-source sur le net.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    [Fausse manip de Loulou24, pas pu récupérer le message original, vraiment désolé ]

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Désolé pour ton message, j'ai fait "éditer" au lieu de "citer"



    Bref, voilà tout de même ma réponse :

    Maintenant cela fonctionne en utilisant unsigned short et unsignet int
    La taille et le codage interne des types pouvant varier d'un système à l'autre, ne compte sur cette solution que si tu ne vises que ta configuration.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Ahhh, alors là tu fais bien de m'en parler... car ce n'est pas le cas, je cherche à porter mon soft (dev sous Mac Os) vers une platerforme autre (win32 voire linux si j'ai le courage de l'installer un jour )

    Alors je me doutais bien que les types ne sont pas les memes sous diverses platerformes (enfin pas définies de la meme taille). Mais voila ce que je pense et que j'aimerai bien que tu valides stp :

    J'ai un fichier que je lis en binaire. Les données dans ce fichier suivent une structure fixe (pour un unsigned int, on lit 4 octets et on les place dans une variable en unsigned int, pour un short on lit 2 octets...).
    Donc grosso modo, la lecture ne se fait pas selon le sizeof(mon type que je veux) mais selon un nombre d'octets que je donne dans mon source.
    De cette maniere cela devrait etre portable non ?

    Voici le code en question :

    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
     
    #define	MAIN_3DS		0x4D4D
    void parse3ds(string filename)
    	{
    	unsigned short Id;
    	unsigned int longueur,index;
     
     
    	ifstream filein(filename.c_str(),ios::binary);
    	if(filein)
    		{
    		index=0;
    		//lecture du premier noeud.
    		filein.read((char*)(&Id),2);
    		index+=2;
    		filein.read((char*)&longueur,4);
    		index+=4;
    		if (Id!=MAIN_3DS)		
    			return;
     
    		}
    	else
    		printf("erreur de lecture de fichier");
    	}
    Je pense (enfin j'espere) que cela devrait passer sur toute plateforme non ?

    Merci d'avance
    ps : pas grave pour le message ^^ c'etait surtout adressé à toi pour te remercier donc comme tu l'as vu c'est good

  6. #6
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    J'ai un fichier que je lis en binaire. Les données dans ce fichier suivent une structure fixe (pour un unsigned int, on lit 4 octets et on les place dans une variable en unsigned int, pour un short on lit 2 octets...).
    Donc grosso modo, la lecture ne se fait pas selon le sizeof(mon type que je veux) mais selon un nombre d'octets que je donne dans mon source.
    De cette maniere cela devrait etre portable non ?
    Et si tu mets 2 octets dans un unsigned short qui en fait 4 par exemple, il va se passer quoi à ton avis ?

    En fait il y a deux solutions :

    - Définir des types de taille fixe, càd tout un tas de directives préprocesseurs pour gérer chaque système... C'est plutôt lourd. De plus il faudra encore gérer l'endianess par dessus ça.

    - Utiliser des buffers de caractères pour récupérer tes données, puis reconstituer les entiers à partir de ses éléments. Avec les fonctions qui vont bien c'est vite géré. Et plus de problème d'endianess, non plus (normalement).

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    En effet, j'avais pas pensé à ça...
    J'ai fait un truc, mais comme je patauge un peu sur les cast, sur ce qu'il se passe dans la machine et tout le tintouin, je ne suis pas ultra sur de mon coup. Voici le code :

    Classe noeud :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class noeud
    	{
    	public:
    		char Idchar;
    		char longueurchar;
    		unsigned short Id;
    		unsigned int longueur;
    	void noeud::caster(void);
    	};
    Sa méthode pour caster les données en type souhaité (donc c'est ici que j'ai mis ma pseudo solution au probleme que tu as soulevé (ou ma solution tout court si elle est bonne ^^)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void noeud::caster(void)
    	{
    	this->Id = (unsigned short)this->Idchar;
    	this->longueur = (unsigned int)this->longueurchar;
    	}
    Enfin, la fonction qui lit un noeud.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    noeud lirenoeud(ifstream &fichier, int &index)
    	{
    	noeud node;
    	fichier.read((char*)&node.Idchar,2);
    	index+=2;
    	fichier.read((char*)&node.longueurchar,4);
    	index+=4;
    	node.caster();
    	return node;
    	}
    Merci d'avance
    ++

    ps : j'espere que ce cast fait le taf

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    J'ai été un peu vite là...
    Ca ne fonctionne pas... je repart à la peche voir ce qui debloque...

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Je pense avoir trouvé une solution, mais je n'en suis pas sur, ne sachant pas ce que fait réellement le reinterpret_cast au niveau du langage machine (s'il convertit bien proprement ou s'il pourrait merder selon les archis des machines).
    Voici le code, qu'en penses tu ?

    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
     
    class noeud
    	{
    	public:
    		unsigned char Idchar[2];
    		unsigned char longueurchar[4];
    		unsigned short Id;
    		unsigned int longueur;
    	void noeud::caster(void);
    	};
     
    void noeud::caster(void)
    	{
    	this->Id = *(reinterpret_cast<unsigned short *>(this->Idchar));
    	this->longueur = *(reinterpret_cast<unsigned int *>(this->longueurchar));
    	}
    Donc pour lire mes noeuds j'utilise ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    noeud lirenoeud(ifstream &fichier, int &index)
    	{
    	noeud node;
    	fichier.read(reinterpret_cast<char*>(&node.Idchar),2);
    	index+=2;
    	fichier.read(reinterpret_cast<char*>(&node.longueurchar),4);
    	index+=4;
    	node.caster();
    	return node;
    	}
    Penses tu donc que je ne risque pas d'avoir de probleme en terme de portabilité ?
    Merci d'avance
    ++

  10. #10
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Il ne faut pas employer de cast, il suffit de recoller correctement les morceaux de ton entier :

    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
    unsigned long Read2Bytes(std::istream& Stream)
    {
        unsigned char Buffer[2];
        Stream.read(reinterpret_cast<char*>(Buffer), 2);
     
        if (LITTLE_ENDIAN) // macro à définir selon le système (PC : little endian ; MAC : big endian)
        {
            return Buffer[0] + (Buffer[1] << 8);
        }
        else
        {
            return Buffer[1] + (Buffer[0] << 8);
        }
    }
     
    unsigned long Read4Bytes(std::istream& Stream)
    {
        unsigned long Buffer[] = {Read2Bytes(), Read2Bytes()};
     
        if (LITTLE_ENDIAN)
        {
            return Buffer[0] + (Buffer[1] << 16);
        }
        else
        {
            return Buffer[1] + (Buffer[0] << 16);
        }
    }
    Un truc dans le genre, modulo les erreurs d'endianess (l'ordre est peut-être inversé).

    Et assure-toi bien que le type de retour (ici unsigned long) est toujours suffisamment grand pour contenir le nombre d'octets que tu lis.

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Arf, là je pleure un peu...
    J'etais parti pour m'amuser avec opengl et j'en arrive à m'enerver sur des Bytes ^^

    Tes fonctions, c'est bien mais sincerement, je ne calcule pas grand chose, du moins, je crois peut etre voir ce que tu fais mais je ne suis pas certain...

    Tu recuperes tes deux octets dans un tableau de char, tu renvoie le char[1]+le car[2] decalé à gauche de 8

    Mais je ne sais pas vraiment ce que c'est censé faire du style, le decalage, ou meme le symbole +

    Je suis vraiment rouillé de chez rouillé sur les bases du C c'est grave ! lol.

    Pour revenir à mon probleme, n'existe-t-il pas de solution toute faite ? enfin une gestion bien implémentée quoi.
    Car bon, moi j'ai juste envie de recuperer des octets et de les mettres dans des variables typées correctement, c'est tout ^^ pas de réinventer le systeme

    Et pourquoi le cast ne fonctionne-t-il pas dans mon cas ? c'est ça que je ne comprend pas en fait.
    Je vais t'expliquer ma logique, tu comprendras peut etre mieux pourquoi je ne comprend pas ^^

    Dans le descriptif du fichier, on me dit, à telle adresse, tu dois recuperer tant d'octets et ces octets representent un int.
    Donc bon, la partie recuperation d'octets, c'est pas bien compliqué, je lui dit d'aller lire le fichier au bon endroit et de recuperer mes N octets.
    Ensuite si je caste, logiquement, il devrait me traduire mes N octets (qui representent d'apres le descriptif un int - et ce, quelque soit la machine) en un type au format de la machine non ?

    Je ne comprend pas à quel endroit c'est censé coincer en faisant ça (bon certes c'est une vision pas très profonde des choses, mais je m'adapte ^^)

    voilou
    ++

    ps : j'avais meme pas grillé que tu etais de Metz, on est à 60 bornes l'un de l'autre ^^ je suis sur nancy

  12. #12
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Tes fonctions, c'est bien mais sincerement, je ne calcule pas grand chose, du moins, je crois peut etre voir ce que tu fais mais je ne suis pas certain...
    Ok, j'explique

    Le but est de récupérer les octets individuellement, puisqu'on ne sait pas dans quel ordre le système les veut. Donc, dans un tableau d'octets (unsigned char). Ensuite, si le système est en big endian (octet de poids fort en premier ou dernier -- me rappelle jamais), il faut recoller les deux morceaux de ton entier dans un certain ordre, si le système est en little endian, l'inverse. Le recollage est effectué en additionnant (on aurait aussi pu utiliser un OU bit à bit, mais l'addition est équivalente puisqu'il n'y a aucun recoupement) les deux octets, mais il faut décaler un octet de 8 bits afin qu'il se place devant l'autre, et non par dessus. Et voilà, tu as formé un entier de 16 bits avec 2 octets. Pour 4, 8, ... c'est pareil, sauf qu'on utilise la fonction qui récupère n/2 octets plutôt que de tout refaire à partir d'un tableau d'octets.

    Dans le descriptif du fichier, on me dit, à telle adresse, tu dois recuperer tant d'octets et ces octets representent un int.
    Donc bon, la partie recuperation d'octets, c'est pas bien compliqué, je lui dit d'aller lire le fichier au bon endroit et de recuperer mes N octets.
    Ensuite si je caste, logiquement, il devrait me traduire mes N octets (qui representent d'apres le descriptif un int - et ce, quelque soit la machine) en un type au format de la machine non ?
    L'erreur est dans
    il devrait me traduire mes N octets (qui representent d'apres le descriptif un int - et ce, quelque soit la machine)
    Le fichier a été enregistré sur une machine bien précise, l'encodage des entiers qui y sont écrits sont donc soumis à la règle d'endianess et de taille propre à cette machine. Comme le logiciel n'est pas con, il a procédé (certainement) de la même manière que moi afin que ceci ne dépende plus de la machine, c'est pourquoi l'ordre et la taille des entiers est donnée explicitement dans la documentation du format.
    De plus reinterpret_cast n'effectue aucune conversion physique, il change juste la manière dont le compilo va interpréter ce qui est pointé.

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Limipide comme de l'eau de vie

    Je comprend dix fois mieux là ! merci pour tes explications ! vraiment c'est sympa !
    Donc si j'ai bien saisi, le probleme d'endianess ne se situe pas sur la machine qui execute mon soft mais au niveau du fichier 3ds en question.

    Donc admettons que je trouve dans le descritpif qu'il s'agisse de l'un ou de l'autre, je pourrais me servir de tes fonctions sans devoir faire le test de l'endianess.

    Si je sais que c'est dans un certain sens, j'ai juste à renvoyer mes octets composés dans le bon sens et c'est tout quoi ?

    En gros, si je voulais pouvoir utiliser ma méthode que j'ai decrit plus bas, il faudrait que mes octets soient décrits à l'endroit.

    Par exemple (et schematiquement):
    J'ai 2 octets A et B
    A et B collés comme ceci AB forment un nombre unsigned short.
    Si dans mon fichier 3ds il sont décrit de poids faible à poids fort ça sera décrit comme ceci :

    XXXXXBAXXXXX (X etant les autres octets contigües)
    Or quand je vais lire, je vais prendre de gauche à droite, donc au final je vais avoir BA dans ma variable de recuperation, ce qui n'est pas bon.
    Par contre, si les octets sont décrit de poids fort à poids faible, j'aurais ça : XXXXXABXXXXX
    je vais donc recuperer AB dans ma variable et alors je pourrais caster tranquille pepere.

    Donc pour résumer, la gestion des endianess dependent du fichier 3ds et non de la machine executant le programme ?

    Si j'ai tout faux, désolé pour l'abberation ^^

  14. #14
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    En fait, la façon dont sont stockés les entiers dans le fichier est figée (et devrait être documentée normalement), c'est par contre bien le système qui va lire ces entiers qui ne vas pas avoir le même système d'endianess. Donc il faut bien adapter les fonctions selon la plateforme sur laquelle tourne le programme.

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Ca y est je viens de piger !
    Effectivement, si tu es sur un systeme ou c'est poids fort -> poids faible et que tu envoies dans cet ordre AB à chaque recuperation, ca ne sera pas pareil sur un systeme ou c'est dans l'ordre inverse.

    Je saisis mieux la subtilité ^^
    Merci beaucoup !

    N'empeche que ça me fait halluciner le nombre de trucs comme ça dont on ne soupsconne meme pas l'existance et qui peuvent tout faire foirer !!!

    Encore merci !

  16. #16
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Loulou24
    En fait, la façon dont sont stockés les entiers dans le fichier est figée (et devrait être documentée normalement), c'est par contre bien le système qui va lire ces entiers qui ne vas pas avoir le même système d'endianess. Donc il faut bien adapter les fonctions selon la plateforme sur laquelle tourne le programme.
    Si tu les recomposes comme tu l'as fait, tu n'as pas à tenir compte de la boutitude de ta machine. C'est bien là l'avantage de la méthode: le fichier a un format bien fixé et le code bien écrit ne dépend pas de la correspondance ou non de ce format avec la représentation utilisée par la machine.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  17. #17
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Si tu les recomposes comme tu l'as fait, tu n'as pas à tenir compte de la boutitude de ta machine. C'est bien là l'avantage de la méthode: le fichier a un format bien fixé et le code bien écrit ne dépend pas de la correspondance ou non de ce format avec la représentation utilisée par la machine.
    Exact j'avais même pas pensé à ça

    Bon ben finalement tout ça devient très simple

  18. #18
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Pour ce genre de choses, il peut être interessant d'utiliser les fonctions htons/ntohs/htonl/ntohl, qui permettent d'enregistrer toujours sur le même format (dit "format réseau", c'est du BigEndian), et de lire correctement selon l'hote qui exécute la lecture...

    Dommage, sous Windows, il faut lier avec Winsock et tout, c'est parfois assez fastidieux...
    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.

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Citation Envoyé par Loulou24
    En fait, la façon dont sont stockés les entiers dans le fichier est figée (et devrait être documentée normalement), c'est par contre bien le système qui va lire ces entiers qui ne vas pas avoir le même système d'endianess. Donc il faut bien adapter les fonctions selon la plateforme sur laquelle tourne le programme.
    Si tu les recomposes comme tu l'as fait, tu n'as pas à tenir compte de la boutitude de ta machine. C'est bien là l'avantage de la méthode: le fichier a un format bien fixé et le code bien écrit ne dépend pas de la correspondance ou non de ce format avec la représentation utilisée par la machine.
    Pourrais tu expliquer un peu plus ce que tu dis stp ?
    De quelle methodes parles tu ?
    Qu'appelles tu "le code bien écrit" ?
    Enfin précises un peu car je ne suis pas sur de comprendre de quoi tu parles en fait ^^

    Merci

  20. #20
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Je pense comprendre ce qui me pose probleme : les pointeurs !!!
    Je connais grosso modo le principe de base, un pointeur est une sorte de variable qui contient l'adresse memoire d'une valeur que l'on a stocké ou d'une variable.
    Le soucis, c'est que là je n'y comprend rien avec cette histoire de buffer et compagnie, c'est une horreur...

    Je voulais donc savoir si quelqu'un pouvait me filer un petit coup de pate en me donnant juste le code de ce que je vais décrire plus bas, comme ça je pourrais au moins savoir vers quoi me diriger et ensuite chercher dans ce sens pour comprendre pourquoi ce code et pas un autre.

    Voila ce que je veux faire pour le moment (pour pouvoir comprendre) :

    Ma fonction principale :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void parseFichier3ds(string filename)
         {
         ifstream fichier(filename.c_str(),ios_base::binary);
         if (fichier)
            {
            fichier.seekg(0,ios_base::end);
            long fsize = fichier.tellg();
            unsigned char buffer[fsize];
            fichier.seekg(0,ios_base::beg);
            fichier.read(reinterpret_cast<char*>(buffer), fsize);
            fichier.close();
            liredonnees(?????);
            }
         }
    ma fonction liredonnees :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void liredonnees(???????? buffer)
         {
         unsigned short ref = 0x4d4d;
         unsigned short id;
         unsigned int longueur;
         id = buffer[1]+(buffer[0]<<8);
         printf("id : %d \n",id);
         printf("reference %d \n",ref);
         }
    Je voulais juste savoir comment vous feriez pour pouvoir acceder au buffer via la fonction ? cet a dire comment passer ce buffer de ma fonction principale à l'autre pour pouvoir y acceder du meme genre que je le fais actuellement ?

    Merci d'avance, ça me permettra de me rafraichir un peu sur les pointeurs et tout le tintouin, malgré mon allergie perpetuelle ^^
    ++

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 4
    Dernier message: 04/06/2007, 14h12
  2. Réponses: 3
    Dernier message: 06/04/2007, 20h06
  3. Problème de comparaison dans une proc
    Par hpavavar dans le forum SQL Procédural
    Réponses: 7
    Dernier message: 27/02/2007, 13h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo