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 :

write(), bytes inversés et supplémentaires


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 6
    Par défaut write(), bytes inversés et supplémentaires
    Bonjour à tous (et toutes),

    Voila mon problème :

    Je voudrais écrire cette structure

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct{
      int i;
      unsigned char vote ;
    } enr;
    dans un fichier de type binaire. Pour faire simple, j'ai un tableau d'un milliard de bits, codé sur 125 millions bytes. Je voudrais sauver seulement les bytes non null (car il y en a que maximum 10 millions qui sont non null), puisque sauver des 0 c'est bien, mais ça prend de la place et c'est null

    J'ai eu l'idée de faire une structure qui prend l'indice dans le tableau, suivit de la valeur, et d'écrire cette structure dans un fichier.

    Voici le code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        int fd = 0;
        char* path = malloc (21);
        path = strcpy(path, getNameBKP());
     
        if((fd = open (path, O_CREAT|O_WRONLY, 00666 )) < 0)
            exit(-1);
     
        int i = -1;
        while(++i < NBVOTER) //NBVOTER = 1 000 000 000 /8 = 125 000 000
            if(vote[i]){
                enr en = {i, vote[i]};
                write(fd, &en, sizeof(en));
            }
        close(fd);
    Le résultat que j'obtiens est assez bizarre.
    Si dans mon tableau je n'ai (en hexa) que 04 à l'indice 3, dans mon fichier j'ai (en hexa) : 03 00 00 00 04 00 00 00

    Si quelqu'un à une idée du pourquoi les bits de poids faible et fort sont inversés, et du comment les remettre dans le bon sens, ou du pourquoi un unsigned char passe sur 32 bits, ce serait chouette.


    Merci d'avance

    Ah oui, petits détails qui éviteront des posts inutiles, les chiffres 10E9 et 10E7 sont fixés, et je ne peux pas les changer, et j'ai pas envie de me retrouver avec des fichiers de 125Mo à chaque fois que je sauve mon tableau.

  2. #2
    Inactif  
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 123
    Par défaut pragma
    Windows ou Linux ?
    ajoute une pragma
    Vois du côté de :pragma

  3. #3
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Jai,

    olivieram a raison : c'est encodé en Little Endian, comme tous les systèmes à base x86 ou x64.

  4. #4
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 6
    Par défaut
    Citation Envoyé par olivieram Voir le message
    Windows ou Linux ?
    ajoute une pragma
    Vois du côté de :pragma
    C'est sous linux (ubuntu 10.04).

    Merci, je regarde ce qu'est une pragma.


    edit:

    Citation Envoyé par droggo Voir le message
    Jai,

    olivieram a raison : c'est encodé en Little Endian, comme tous les systèmes à base x86 ou x64.
    OK, je m'y connais pas trop en type de codages. Il y a plusieurs manières d'encoder dans un fichier?

  5. #5
    Inactif  
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 123
    Par défaut encoder dans un fichier
    Non, il n'y a pas plusieurs manières d'écrire dans un fichier.
    Cela s'appelle en fait des "facilities" parce que le fonctionnement de la librairie fournit, en standard, la possibilité d'écrire dans un format d'encodage particulier. Il s'agit le plus souvent de UTF-8, ISO ou Unicode pour du texte.

  6. #6
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 6
    Par défaut
    Pour les bytes en trop, j'ai trouvé une solution dégueulasse mais qui marche, au lieu d'écrire ma structure en une fois, j'écris d'abord le int, puis le unsigned char.

    Apparemment, sizeof(enr) = 8, sizeof(enr.i) = 4 et sizeof(enr.vote) = 1, d'ou 4 +1 => 8
    Un petit truc de fou qui sort de nulle part, et qui alimente les forums.


    Citation Envoyé par olivieram Voir le message
    Non, il n'y a pas plusieurs manières d'écrire dans un fichier.
    Cela s'appelle en fait des "facilities" parce que le fonctionnement de la librairie fournit, en standard, la possibilité d'écrire dans un format d'encodage particulier. Il s'agit le plus souvent de UTF-8, ISO ou Unicode pour du texte.
    Sinon je cherche toujours pour écrire de hb vers lb, ou lire de lb vers hb. Si tu as une idée de la ligne qu'il faut taper pour changer le format d'encodage (si vraiment ça change quelque chose).
    Merci d'avance.

    EDIT:
    Je viens de réessayer de lire le fichier, et apparemment ça ne pose pas de problème que ce soit écrit à l'envers, il me lis bien tous les éléments. Donc c'était juste un problème à cause de la structure, avec des bytes en trop lors de l'écriture.

    Un grand Merci à ceux qui ont répondu au post!

  7. #7
    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
    C'est pour cette raison qu'il est déconseillé d'écrire directement une structure dans un fichier binaire. Tu devrais en sérialiser le contenu toi-même pour l'écriture:
    Code C : 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
    void write_uint(FILE* pfOut, unsigned int val)
    {
    	const unsigned int BITS_RIGHT = (sizeof(int)-1) * CHAR_BIT;
    	const unsigned int LSBITS = ((unsigned int)-1) >> BITS_RIGHT;
    	for(int i=0 ; i<sizeof(int) ; i++)
    	{
    		fputc((val >> BITS_RIGHT) & LSBITS, pfOut);
    		val <<= CHAR_BIT;
    	}
    }
    unsigned int read_uint(FILE* pfIn)
    {
    	unsigned int val = 0;
    	for(int i=0 ; i<sizeof(int) ; i++)
    	{
    		val <<= CHAR_BIT;
    		val |= fgetc(pfIn);
    	}
    }
     
    void write_int(FILE* pfOut, int val)
    { write_uint(pfOut, (unsigned int)val; }
     
    int read_int(FILE* pfIn)
    { return (int)read_uint(pfIn); }
     
    void write_struct_enr(FILE* pfOut, enr const *pcObj)
    {
    	write_int(pfOut, pcObj->i);
    	fputc(pcObj->vote, pfOut);
    }
    void read_struct_enr(FILE* pfIn, enr *pObj)
    {
    	pObj->i = read_int(pfIn);
    	pObj->vote = fgetc(pfIn);
    }
    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.

  8. #8
    Inactif  
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 123
    Par défaut
    Citation Envoyé par tompus Voir le message
    Sinon je cherche toujours pour écrire de hb vers lb, ou lire de lb vers hb. Si tu as une idée de la ligne qu'il faut taper pour changer le format d'encodage (si vraiment ça change quelque chose).
    Merci d'avance.
    hb signifie high-byte et lb signifie low-byte ?

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

Discussions similaires

  1. Port sériel et méthode Write(byte[],offset,length)
    Par TheCaribouX dans le forum C#
    Réponses: 6
    Dernier message: 02/06/2008, 17h10
  2. [C#] Conversion d'un byte[] en byte *
    Par karsh dans le forum Windows Forms
    Réponses: 6
    Dernier message: 08/12/2004, 10h53
  3. [STRUTS] bean:write
    Par lfournial dans le forum Struts 1
    Réponses: 3
    Dernier message: 30/01/2004, 09h58
  4. transtyper ^dword en ^byte ?
    Par - Robby - dans le forum Langage
    Réponses: 3
    Dernier message: 28/10/2003, 00h58
  5. write() dans une socket.. unix
    Par slack dans le forum Réseau
    Réponses: 5
    Dernier message: 18/12/2002, 20h42

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