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 :

Ecriture Binaire/Problème d'endianess


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2011
    Messages : 91
    Par défaut Ecriture Binaire/Problème d'endianess
    Bonjour à tous,

    J'essaye de réaliser un programme qui puisse écrire le contenu de variable en mode binaire dans un fichier. j'ai déjà posté sur dans la section Qt vu que je l'utilise mais je pense que la solution peut se trouver sans cette librairie, juste avec le C++.
    Je dois pouvoir écrire ces variables en big ou little endian et ce peut importe ma machine.

    Je m'y suis pris comme cela :
    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
    quint64 qi1 = 127;
    quint64 qi2 = 18;
    quint64 qi3 = 1;
    quint64 qi4 = 10;
    qint64 qi5 = 11;
    qint64 qi6 = 4660;
    // Je dois écrire ces variables en big endian dans cette exemple
    FILE* fichier;
    fichier = fopen("lol", "wb");
    fwrite(&qi1, 2, 1, fichier); // l'access size de i1 est de 2
    fwrite(&qi2, 1, 1, fichier); // l'access size de i2 est de 1
    fwrite(&qi3, 1, 1, fichier); // l'access size de i3 est de 1
    fwrite(&qi4, 1, 1, fichier); // l'access size de i4 est de 1
    fwrite(&qi5, 1, 1, fichier); // l'access size de i5 est de 1
    fwrite(&qi6, 2, 1, fichier); // l'access size de i6 est de 2
    fclose(fichier);
    Sur Ubuntu j'obtiens dans mon fichier (hexdump) :
    007f 0112 0b0a 1234
    Sur Windows j'obtiens :
    7f00 1201 0a0b 3412
    Hélas mon responsable me dit que je dois obtenir :
    007f 12 01 0a0b 1234
    Je suis vraiment pas calé dans ce domaine, je sais pas si je m'y prends bien ou si je dois faire autrement.
    Si quelqu'un a une idée (pas trop compliqué (genre décallage de bit ), je le remercie)

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ce que ton responsable demande, c'est du big-endian, mais sur des nombres de la bonne taille, pas sur des int64.

    Il te faut un truc du genre:
    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    void writeI1(unsigned char val, FILE *fout)
    {
    	unsigned char c[1];
    	c[0] = (unsigned char)(val);
    	fwrite(c, 1, 1, fout);
    }
    #define writeI1BE writeI1
    #define writeI1LE writeI1
     
    void writeI2BE(unsigned short val, FILE *fout)
    {
    	unsigned char c[2];
    	c[0] = (unsigned char)(val >> 8);
    	c[1] = (unsigned char)(val);
    	fwrite(c, 1, 2, fout);
    }
     
    void writeI2LE(unsigned short val, FILE *fout)
    {
    	unsigned char c[2];
    	c[0] = (unsigned char)(val);
    	c[1] = (unsigned char)(val >> 8);
    	fwrite(c, 1, 2, fout);
    }
     
    void writeI4BE(unsigned long val, FILE *fout)
    {
    	unsigned char c[4];
    	c[0] = (unsigned char)(val >> 24);
    	c[1] = (unsigned char)(val >> 16);
    	c[2] = (unsigned char)(val >> 8);
    	c[3] = (unsigned char)(val);
    	fwrite(c, 1, 4, fout);
    }
     
    void writeI4LE(unsigned long val, FILE *fout)
    {
    	unsigned char c[4];
    	c[0] = (unsigned char)(val);
    	c[1] = (unsigned char)(val >> 8);
    	c[2] = (unsigned char)(val >> 16);
    	c[3] = (unsigned char)(val >> 24);
    	fwrite(c, 1, 4, fout);
    }
     
    void writeI8BE(unsigned long long val, FILE *fout)
    {
    	unsigned char c[8];
    	c[0] = (unsigned char)(val >> 56);
    	c[1] = (unsigned char)(val >> 48);
    	c[2] = (unsigned char)(val >> 40);
    	c[3] = (unsigned char)(val >> 32);
    	c[4] = (unsigned char)(val >> 24);
    	c[5] = (unsigned char)(val >> 16);
    	c[6] = (unsigned char)(val >> 8);
    	c[7] = (unsigned char)(val);
    	fwrite(c, 1, 8, fout);
    }
     
    void writeI8LE(unsigned long long val, FILE *fout)
    {
    	unsigned char c[8];
    	c[0] = (unsigned char)(val);
    	c[1] = (unsigned char)(val >> 8);
    	c[2] = (unsigned char)(val >> 16);
    	c[3] = (unsigned char)(val >> 24);
    	c[4] = (unsigned char)(val >> 32);
    	c[5] = (unsigned char)(val >> 40);
    	c[6] = (unsigned char)(val >> 48);
    	c[7] = (unsigned char)(val >> 56);
    	fwrite(c, 1, 8, fout);
    }
    Bien sûr, on peut sans doute faire plus rapide et moins répétitif. Mais cette version est, je trouve, la plus facile à comprendre qui soit indépendante de l'endianness de la machine.
    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.

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2011
    Messages : 91
    Par défaut
    Merci beaucoup ça marche niquel et je comprends a peu près le principe
    J’implémente ça dans mon code et je reviendrai pour une autre question !

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Juste une remarque: Si tu as accès à des types à taille fixe (int64, int8, etc.) utilise-les à la place de char, short, long, et long long dans mon code.
    Surtout long, sa taille n'est pas garantie être 32 bits (beaucoup de plate-formes 64 bits *n*x sont en LP64 au lieu de LLP64).
    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.

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2011
    Messages : 91
    Par défaut
    Ok merci.
    Donc à la place d'utiliser unsigned char, unsigned short, unsigned long et unsigned long long. Je dois utiliser respectivement int8_t, int16_t, int32_t, int64_t? Ou peut être les uintn_t?

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Plutôt les uintN_t. Quand on bosse avec ce genre de trucs, autant rester non-signé.
    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.

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    Est-on toujours dans le forum C++ ?
    Toutes ces solutions sont du C. Je suis le premier à utiliser du "code C" quand besoin/envie/whatever, mais faudrait savoir ce que l'on veut.
    Un bon coup de template spécialiser serait des plus efficace.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Je n'avais même pas remarqué qu'on était dans le forum C++, en fait, vu que le premier message utilisait fwrite...
    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.

  9. #9
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Bonsoir,

    Est-on toujours dans le forum C++ ?
    Toutes ces solutions sont du C. Je suis le premier à utiliser du "code C" quand besoin/envie/whatever, mais faudrait savoir ce que l'on veut.
    Un bon coup de template spécialiser serait des plus efficace.
    C'est vrai, mais l'algo (aussi simple soit-il) est beaucoup moins facile à comprendre, il se retrouve perdu au milieu de templates.
    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
    #include <iostream>
    #include <fstream>
    #include <stdint.h>
     
    template <size_t> struct unsigned_ { };
    template <> struct unsigned_<1> { typedef uint8_t type; };
    template <> struct unsigned_<2> { typedef uint16_t type; };
    template <> struct unsigned_<4> { typedef uint32_t type; };
    template <> struct unsigned_<8> { typedef uint64_t type; };
     
    template <class T>
    void write(T val, std::ostream& os, bool big_endian=true) {
    	const size_t size = sizeof(T);
    	typedef unsigned_<size>::type type;
    	for(size_t i=0; i<size; ++i) {
    		type *ptr = reinterpret_cast<type*>(&val);
    		os << static_cast<unsigned char>(((*ptr) >> (big_endian ? size-i-1: i)*8));
    	}
    }
     
    int main() {
     
    	std::ofstream file("tmp", std::ios::binary);
     
    	write(uint16_t(127), file);
    	write(uint8_t(18), file);
    	write(uint8_t(1), file);
    	write(uint8_t(10), file);
    	write(uint8_t(11), file);
    	write(uint16_t(4660), file);
     
    	write(42.f, file); // float
    	write(42.0, file); // double
     
    	file.close();
     
    	return 0;
    }

  10. #10
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2011
    Messages : 91
    Par défaut
    typedef unsigned_<size>::type type;
    Il manque un typename entre typedef et unsigned_ et ça marche bien sur Windows. Par contre sur ma ubuntu j'obtiens : 7f00 0112 0b0a 3412. Ce qui n'est pas ce que je recherche

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Sur ta machine Ubuntu, CHAR_BIT est bien égal à 8?
    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.

  12. #12
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2011
    Messages : 91
    Par défaut
    Avec limits.h CHAR_BIT vaut bien 8 sur ma machine Ubuntu

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Buffer d'ecriture fichier problème
    Par xokami35x dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 14/09/2009, 20h40
  2. Ecriture binaire d'un vector
    Par NiamorH dans le forum SL & STL
    Réponses: 8
    Dernier message: 20/01/2008, 17h28
  3. [Lecture binaire] Problème de conversion
    Par poukill dans le forum C++
    Réponses: 2
    Dernier message: 14/09/2007, 09h34
  4. Ecriture binaire en sortie
    Par mioux dans le forum Coldfusion
    Réponses: 2
    Dernier message: 27/06/2007, 14h20
  5. [Méthode de tri][Arbre binaire] Problème dans l'ordre total
    Par jgavard dans le forum Collection et Stream
    Réponses: 1
    Dernier message: 24/04/2007, 16h55

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