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 dans un fichier en mode binaire


Sujet :

C

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 33
    Points : 12
    Points
    12
    Par défaut Ecriture dans un fichier en mode binaire
    Bonjour,

    Je voudrai écrire dans un fichier en mode binaire mais je ne sais pas trop comment il faut faire.
    Donc en fait, par ex si je stocke une variable int dans un fichier, ca utilise 4 octets. (pas plus, pas moins)

    j'ai pensé à ca pour le mode d'ajout par exemple si je veux rajouter du contenu à un fichier: "ab".
    Déjà, je suis pas certain de ce que je dis donc, voilà pourquoi je post et aussi pour savoir les fonctions à utilisé et comment les utilisés. (je suppose que c'est un fwrite et non pas un fputs)

    Merci d'avance.

  2. #2
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par greg1517 Voir le message
    Je voudrai écrire dans un fichier en mode binaire mais je ne sais pas trop comment il faut faire.
    Donc en fait, par ex si je stocke une variable int dans un fichier, ca utilise 4 octets. (pas plus, pas moins)
    C'est pas très clair. Si le format des données du fichier binaire a été défini de façon claire et indépendante de l'architeture (format réseau, par exemple, MSB en tête etc.), il suffit de suivre ces indications.
    Pas de Wi-Fi à la maison : CPL

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 33
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    C'est pas très clair. Si le format des données du fichier binaire a été défini de façon claire et indépendante de l'architeture (format réseau, par exemple, MSB en tête etc.), il suffit de suivre ces indications.
    Merci pour ta réponse.
    Je vais reformuler ma phrase autrement.
    J'ai par exemple une variable de type int qui vaut 57287 par exemple.
    Je voudrai en fait le mettre dans un fichier simplement mais doit utiliser 4 octets.
    Voilà.

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par greg1517 Voir le message
    J'ai par exemple une variable de type int qui vaut 57287 par exemple.
    Je voudrai en fait le mettre dans un fichier simplement mais doit utiliser 4 octets.
    Mais ça ne dit pas à quoi correspondent ces octets. Le format 'réseau' est une norme bien connue (MSB en tête). C'est ça que tu veux ?

    57287 vaut DFC7 en hexadécimal.

    Est-ce que tu veux MSB en tête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    [0] 0x00
    [1] 0x00
    [2] 0xDF
    [3] 0xC7
    ou LSB en tête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    [0] 0xC7
    [1] 0xDF
    [2] 0x00
    [3] 0x00
    voire d'autres combinaisons étranges...
    Pas de Wi-Fi à la maison : CPL

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 33
    Points : 12
    Points
    12
    Par défaut
    Merci beaucoup.

    C'est bon.
    Mais maintenant, comment écrire dans le fichier toujours sur 4 octets (même si c'est 3 milliard)?

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    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 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Si ton nombre est signé, tu ne pourras pas écrire trois milliards sur quatre octets.
    En non-signé par contre, tu peux aller jusqu'à un peu plus de quatre milliards.
    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
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 33
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Si ton nombre est signé, tu ne pourras pas écrire trois milliards sur quatre octets.
    En non-signé par contre, tu peux aller jusqu'à un peu plus de quatre milliards.
    Je le sais ca, ca m'aide pas lol.
    Non il est non signé évidemment, je connais quand même le strict minimum du C (c'est la première chose qu'on apprend sur les variables lol)

    Enfin merci quand même pour ta réponse.

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par greg1517 Voir le message
    comment écrire dans le fichier toujours sur 4 octets (même si c'est 3 milliard)?
    Tu mets les 4 octets dans le bon ordre (avec << | etc.) dans un tableau de 4 unsigned char et tu écris ce tableau dans le fichier avec fwrite().

    http://emmanuel-delahaye.developpez.com/bits.htm

    Fait de ton mieux et poste ton code si tu as un problème.
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 33
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Tu mets les 4 octets dans le bon ordre (avec << | etc.) dans un tableau de 4 unsigned char et tu écris ce tableau dans le fichier avec fwrite().

    http://emmanuel-delahaye.developpez.com/bits.htm

    Fait de ton mieux et poste ton code si tu as un problème.
    D'accord, merci beaucoup.
    Je vais essayé ca.

  10. #10
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par greg1517 Voir le message
    Bonjour,

    Je voudrai écrire dans un fichier en mode binaire mais je ne sais pas trop comment il faut faire.
    Donc en fait, par ex si je stocke une variable int dans un fichier, ca utilise 4 octets. (pas plus, pas moins)
    Pas garanti! La norme assure qu'un entier de type int est représenté sur au moins 16 bits (en fait, la norme ne parle pas de bits mais défini des valeurs minimales et maximales représentables pas un entier de type int).

    Voici un petit exemple écrit un peu en vitesse:

    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
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    #include <stdio.h>
    #include <stdlib.h>
     
    static int
    ecrire_int(int d, FILE *fp)
    {
        int err = 0;
     
        if (fp != NULL)
        {
            unsigned char tampon[2] = {0};
            int rv;
            /* -tc- gestion speciale des entiers negatifs pour tenir compte des
                architectures ou les nombres negatifs ne sont pas representes par
                complement a deux comme sur ma machine */
            unsigned int donnee = (d >= 0) ? d : -d + 0x7fffU;
     
            /* -tc- on decide qu'un entier de type int est represente sur au plus 2
               octets, grand boutiste */
            tampon[1] = (donnee >> 0) & 0xff;
            tampon[0] = (donnee >> 8) & 0xff;
     
            rv = fwrite(tampon, 1, sizeof tampon, fp);
            /* -tc- on verifie que toutes les donnees ont ete ecrites dans le fichier */
            if (rv != sizeof tampon)
            {
                /* -tc- Erreur: ecriture des donnees incomplete */
                err = 1;
            }
        }
        else
        {
            /* -tc- Erreur: argument invalide! */
            err = 2;
        }
        return err;
    }
     
    static int
    lire_int(int *p, FILE *fp)
    {
        int err = 0;
     
        /* -tc- on verifie la validite des arguments */
        if (p != NULL && fp != NULL)
        {
            unsigned char tampon[2] = {0};
            unsigned int donnee = 0;
            int rv = 0;
     
            rv = fread(tampon, 1, sizeof tampon, fp);
            /* -tc- on verifie que la lecture est complete */
            if (rv == sizeof tampon)
            {
                donnee = donnee | (tampon[0] << 8);
                donnee = donnee | (tampon[1] << 0);
     
                *p = (donnee > 0x7fffU) ? -(donnee - 0x7fffU) : donnee;
            }
            else
            {
                /* -tc- Erreur de lecture ou EOF */
                if (feof(fp) != 0)
                {
                    err = EOF;
                }
                else
                {
                    err = 1;
                }
            }
     
        }
        else
        {
            /* -tc- Erreur: argument invalide */
            err = 2;
        }
        return err;
    }
     
     
    int main(void)
    {
        int entier = 32767;
        FILE *fichier = NULL;
        int ret = EXIT_SUCCESS;
     
        /* -tc- on ouvre le fichier en ecriture en mode binaire*/
        fichier = fopen("mon-fichier.dat", "wb");
        if (fichier != NULL)
        {
            int err = 0;
     
            err = ecrire_int(entier, fichier);
            if (err != 0)
            {
                fprintf(stderr, "Erreur d'ecriture!\n");
                ret = EXIT_FAILURE;
            }
            fclose(fichier), fichier = NULL;
        }
        else
        {
            fprintf(stderr, "impossible d'ouvrir le fichier en ecriture!\n");
            ret = EXIT_FAILURE;
        }
     
        /* -tc- on ouvre le fichier en lecture en mode binaire */
        fichier = fopen("mon-fichier.dat", "rb");
        if (fichier != NULL)
        {
            int err = 0;
     
            err = lire_int(&entier, fichier);
            if (err != 0)
            {
                fprintf(stderr, "Erreur de lecture ou fin de fichier!\n");
                ret = EXIT_FAILURE;
            }
     
            printf("entier vaut %d\n", entier);
            fclose(fichier), fichier = NULL;
        }
        else
        {
            fprintf(stderr, "impossible d'ouvrir le fichier en lecture!\n");
            ret = EXIT_FAILURE;
        }
     
        return ret;
    }
    Je vais commenter un peu, mais n'hésite pas à poser des questions si tu as des soucis avec mon code.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 33
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Tu mets les 4 octets dans le bon ordre (avec << | etc.) dans un tableau de 4 unsigned char et tu écris ce tableau dans le fichier avec fwrite().

    http://emmanuel-delahaye.developpez.com/bits.htm

    Fait de ton mieux et poste ton code si tu as un problème.
    Merci. j'ai fait et ca marche, apparement c'est bien ce que j'attendais.
    mais maintenant, comment lire le fichier et récupérer la valeur en supposant dans l'exemple que la valeur de la variable de type int est 3680945354 et non signé bien entendu.

    PS: n'y a t-il pas aussi un moyen plus direct pour passer d'un entier vers la base 256?

  12. #12
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par greg1517 Voir le message
    Merci. j'ai fait et ca marche, apparement c'est bien ce que j'attendais.
    mais maintenant, comment lire le fichier et récupérer la valeur en supposant dans l'exemple que la valeur de la variable de type int est 3680945354 et non signé bien entendu.
    De la même manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    {
       unsigned long value = 0;
       unsigned char data[4];
       fread(data, sizeof data, 1, fp);
     
       value  |= (data[0] << (8 * 3)); /* MSB en tete */
       value  |= (data[1] << (8 * 2));
       value  |= (data[2] << (8 * 1));
       value  |= (data[3] << (8 * 0));
    }
    PS: n'y a t-il pas aussi un moyen plus direct pour passer d'un entier vers la base 256?
    Je ne vois pas trop de quoi tu parles. Ce qu'on indique ici, ce sont des méthodes portables indépendantes de l'architecture matérielle.
    Pas de Wi-Fi à la maison : CPL

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 33
    Points : 12
    Points
    12
    Par défaut
    Bonjour,

    Récupérer le résultat est autre chose.
    Voici mon code plus ou moins complet (sans commentaire) en supposant que l'entier de départ est 3680945354 et qui donne DB66C4CA en hexadécimal. (int non signé évidemment, inutile de le préciser)

    J'ai utilisé le MSB en tête.

    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
     
    char unsigned a[4];
    a[0]=0xDB;
    a[1]=0x66;
    a[2]=0xC4;
    a[3]=0xCA;
     
    FILE *fichier=NULL;
    fichier=fopen("test.txt", "w+");
    fwrite(a, 1, 4, fichier);
    fclose(fichier);
     
    //LECTURE
    unsigned int id=0;
    char unsigned buffer2[4];
    fichier=fopen("test.txt", "r");
    fread(buffer2, 1, sizeof buffer2, fichier);
    id |= (buffer2[0] << (8*3));
    id |= (buffer2[1] << (8*2));
    id |= (buffer2[2] << (8*1));
    id |= (buffer2[3] << (8*0));
    Le problème: id n'est pas égal à 3680945354.
    Merci d'avance.

  14. #14
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par greg1517 Voir le message
    Bonjour,

    Récupérer le résultat est autre chose.
    Voici mon code plus ou moins complet (sans commentaire) en supposant que l'entier de départ est 3680945354 et qui donne DB66C4CA en hexadécimal. (int non signé évidemment, inutile de le préciser)

    J'ai utilisé le MSB en tête.
    <...>
    Le problème: id n'est pas égal à 3680945354.
    Merci d'avance.
    Comment tu le sais ? Ton code ne permet pas de la savoir, il est incomplet, et mon petit doigt me dit que tu as oublié une information essentielle lors de l'affichage : 'unsigned' .

    Ceci fonctionne :
    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
     
    #include <stdio.h>
     
    int main (void)
    {
       {
          char unsigned a[4];
     
          /* conversion */
          {
             unsigned long id = 3680945354UL;
     
             a[0] = (id >> (8 * 3)) & 0xFF; /* MSB */
             a[1] = (id >> (8 * 2)) & 0xFF;
             a[2] = (id >> (8 * 1)) & 0xFF;
             a[3] = (id >> (8 * 0)) & 0xFF;
             printf ("id = %08lX (%lu)\n", id, id);
          }
     
          /* ecriture */
          {
             FILE *fichier = fopen ("test.txt", "wb");
             if (fichier != NULL)
             {
                fwrite (a, 1, sizeof a, fichier);
                fclose (fichier);
             }
          }
       }
     
       {
          char unsigned buffer2[4];
     
          /* LECTURE */
          {
             FILE *fichier = fopen ("test.txt", "rb");
             if (fichier != NULL)
             {
                fread (buffer2, 1, sizeof buffer2, fichier);
                fclose (fichier);
             }
          }
     
          /* conversion */
          {
             unsigned long id = 0;
             id |= (buffer2[0] << (8 * 3)); /* MSB */
             id |= (buffer2[1] << (8 * 2));
             id |= (buffer2[2] << (8 * 1));
             id |= (buffer2[3] << (8 * 0));
             printf ("id = %08lX (%lu)\n", id, id);
          }
       }
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    id = DB66C4CA (3680945354)
    id = DB66C4CA (3680945354)
     
    Press ENTER to continue.
    Pas de Wi-Fi à la maison : CPL

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 33
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Comment tu le sais ? Ton code ne permet pas de la savoir, il est incomplet, et mon petit doigt me dit que tu as oublié une information essentielle lors de l'affichage : 'unsigned' .
    Oups, une bête erreur...
    Merci, je pensais justement à cette erreur.

    Je remercie en particulier Emmanuel, super modérateur.

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

Discussions similaires

  1. Problème d'écriture dans un fichier en mode binaire
    Par Linkht dans le forum Général Python
    Réponses: 6
    Dernier message: 11/08/2011, 03h41
  2. Lecture ecriture dans un fichier binaire
    Par laetous dans le forum C
    Réponses: 13
    Dernier message: 26/08/2006, 08h50
  3. ouverture/lecture/ecriture dans un fichier en mode binaire
    Par dirty_boy dans le forum Débuter
    Réponses: 2
    Dernier message: 15/03/2006, 08h38
  4. Probleme d'ecriture dans un fichier en mode Text
    Par bbozet dans le forum C++Builder
    Réponses: 3
    Dernier message: 14/01/2004, 13h46
  5. [LG]ecriture dans un fichier binaire
    Par jsaviola dans le forum Langage
    Réponses: 3
    Dernier message: 26/12/2003, 17h30

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