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 :

Ouvrir un fichier en mode binaire ?


Sujet :

C++

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 412
    Par défaut Ouvrir un fichier en mode binaire ?
    Bonjours,

    J'ai regarder la fonction suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::ifstream I("fichier.bin",std::ios::binary);
    Mai sa ne me renvoie pas des 0 ou 1.
    Si je ne me trompe pas sur le disque c'est bien stoquer sur cette forme, il y a un truc qui m'échappe

    c'est pour travailler sur des fichier pouvant être de n'importe qu'elle taille , et évidement pas ce taper les caractères exotique qui ce trouve dedans.

    Merci d'avance

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Déjà, il faut savoir qu'un fichier est forcément écrit sous forme de bits (mieux, sous forme de bytes) sur un disque dur, car c'est la seule possibilité qui existe; chaque bit sur le disque dur ne pouvant prendre que deux valeurs possibles : 1(le courant passe) ou 0 (le courant ne passe pas)

    Le mode d'ouverture ne nous permet que de changer la manière d'interpréter les différents bytes qui composent le fichier:

    En mode texte, on considère que chaque caractère est représenté par un byte (typiquement 8 bits), si bien qu'il faudra lire ... 5 byte pour lire la valeur 12345.

    En mode binaire, on considère que chaque information est écrite sous une forme qui correspond à sa représentation en mémoire. Par exemple, une donnée de type int sera, typiquement, représentée grâce à 4 byte (soit ... 32 bits), si bien qu'il ne faudra lire que 4 bytes pour obtenir la valeur 12345.

    C'est la seule différence qui existe entre les deux types de fichiers!

    Ensuite, il faut savoir que, lorsqu'on lit un fichier ouvert en mode binaire, on ne lit pas les bits un à un: on lit forcément l'équivalent de un byte (à savoir, typiquement, 8 bits).

    Il n sert donc à rien de t'attendre à recevoir des 0 et des 1 (qui ne sont d'ailleurs que la représentation conventionnelle de représenter le passage ou non du courant dans un circuit électrique): au minimum, tu pourras lire 1 byte, soit 8 bits, ce qui te permettra d'obtenir une valeur numérique comprise entre 0 et 255 inclus.

    Notes au passage que la norme de 2017 nous a fourni un nouveau type de donnée capable de représenter cette notion de byte : std::byte, alors que, avant, nous aurions sans doute utilisé le type unsigned char.

    L'énorme avantage étant que, vu que l'on considère que les informations lues correspondent à des valeurs numériques, on évite tous les problèmes liés à ce que l'on appelle les "caractères non affichables", qui correspondent aux caractères ayant un indice compris entre 0 et 31 inclus dans la table ASCII.

    Pour lire le contenu d'un fichier ouvert en binaire, une des solutions est donc de ... lire chaque byte qui le compose "l'un à la suite de l'autre", pour les placer en mémoire (sous la forme d'un std::vector<std::byte> ou d'un std::vector<unsigned char>).

    Mais il faut aussi savoir qu'il est tout à fait possible de lire "un certain nombre de bytes" en une fois, ce qui nous permet, si l'on peut déterminer le type de la donnée qui doit être lue, de lire un entier (type int), par exemple à l'aide d'un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::ifstream ifs("fichier.dat", std::ios::binary); le fichier en mode binaire
     
    int myInt;
    ifs.read(reinterpret_cast<char*>(&myInt), sizeof(int));
    et qui, mieux encore, nous permet d'extraire d'une seule traite les information de n'importe quelle structure (qui ne contienne pas de pointeur) sous une forme proche de
    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
    /* la structure que l'on s'apprête à lire */
    struct Point{
        int x;
        int y;
    }
    int main(){
        std::ifstream ifs{"allPoints.dat", std::ios::binary}; // le fichier qu'on va lire
        Point temp;   // une donnée temporaire pour la lecture
        std::vector<Point> tab; //le tableau de points résultant
        while(ifs){
            ifs.read(reinterpret_cast<char*>(&temp), sizeof(Point));
            tab.push_back(temp);
        }
        /* on peut utiliser le tableau de points ici */
    }
    Et, pour terminer, un peu de lecture:
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 412
    Par défaut
    Merci pour ta réponse claire et précise

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 412
    Par défaut
    Quand j'utilise l'idée citée plus haut, il n'y a pas de lecture vraiment binaire on dirait voici un code compilable:

    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
     
     
    #include <iostream>
    #include <fstream>
    //using namespace std;
     
    int main()
    {
        struct Point{
            long x = NULL ;
            long y = NULL ;
        };
        Point temp;
        long maxcount = NULL;
        std::string nomFichier = "connexions.txt";
        std::ifstream Fichier(nomFichier.c_str(), std::ios_base::binary);
        if(Fichier.is_open() == 0) {
            std::cout << "Erreur de lecture de fichier" << std::endl;
            return 1;
        }
        else
        {
            std::cout << "Ouverture du fichier:" << nomFichier << std::endl;
        }
     
         while(Fichier){
            Fichier.read(reinterpret_cast<char*>(&temp), sizeof(Point));
            maxcount = maxcount + temp.y ;
            std::cout <<  temp.y <<  " " << maxcount  << std::endl;
        }
     
        return 0;
    }
    le fichier contien du texte pour l'essais.
    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
     
    y
    z
    1
    2
    3
    4
    5
    6
    7
    8
    9
    0
     
     
     
     
    ========================================================================
    	123
    		124
    ================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
    la sortie est la suivante:
    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
     
    221317645 221317645
    873073971 1094391616
    168637962 1263029578
    221841933 1484871511
    168626701 1653498212
    1027423549 -1614045535
    1027423549 -586621986
    1027423549 440801563
    1027423549 1468225112
    1027423549 -1799318635
    1027423549 -771895086
    1027423549 255528463
    1027423549 1282952012
    1027423549 -1984591735
    822675981 -1161915754
    842074377 -319841377
    1027423549 707582172
    1027423549 1735005721
    1027423549 -1532538026
    1027423549 -505114477
    1027423549 522309072
    1027423549 1549732621
    1027423549 -1717811126
    1027423549 -690387577
    1027423549 337035972
    1027423549 1364459521
    1027423549 -1903084226
    1027423549 -875660677
    1027423549 151762872
    1027423549 1179186421
    1027423549 -2088357326
    1027423549 -1060933777
    1027423549 -33510228
    1027423549 993913321
    1027423549 2021336870
    1027423549 -1246206877
    1027423549 -218783328
    1027423549 808640221
    1027423549 1836063770
    1027423549 -1431479977
    1027423549 -404056428
    1027423549 623367121
    1027423549 1650790670
    1027423549 -1616753077
    1027423549 -589329528
    1027423549 438094021
    1027423549 1465517570
    1027423549 -1802026177
    1027423549 -774602628
    1027423549 252820921
    1027423549 1280244470
    1027423549 -1987299277
    1027423549 -959875728
    1027423549 67547821
    1027423549 1094971370
    1027423549 2122394919
    1027423549 -1145148828
    1027423549 -117725279
    1027423549 909698270
    1027423549 1937121819
    1027423549 -1330421928
    1027423549 -302998379
    1027423549 724425170
    1027423549 1751848719
    1027423549 -1515695028
    1027423549 -488271479
    1027423549 539152070
    1027423549 1566575619
    1027423549 -1700968128
    1027423549 -673544579
    1027423549 353878970
    1027423549 1381302519
    1027423549 -1886241228
    1027423549 -858817679
    1027423549 168605870
    1027423549 1196029419
    1027423549 -2071514328
    1027423549 -1044090779
    1027423549 -16667230
    1027423549 1010756319
    1027423549 2038179868
    1027423549 -1229363879
    1027423549 -201940330
    1027423549 825483219
    1027423549 1852906768
    1027423549 -1414636979
    1027423549 -387213430
    1027423549 640210119
    1027423549 1667633668
    1027423549 -1599910079
    1027423549 -572486530
    1027423549 454937019
    1027423549 1482360568
    1027423549 -1785183179
    1027423549 -757759630
    1027423549 269663919
    1027423549 1297087468
    1027423549 -1970456279
    1027423549 -943032730
    1027423549 84390819
    1027423549 1111814368
    1027423549 2139237917
    1027423549 -1128305830
    1027423549 -100882281
    1027423549 926541268
    1027423549 1953964817
    1024068873 -1316933606
    il est claire que j'ai rater quelque chose, m'enfin afficher un long + un long qui donne un résultat pareil c est pas mal ....

    Merci pou votre patience

  5. #5
    Membre expérimenté
    Homme Profil pro
    Développeur
    Inscrit en
    Août 2011
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Août 2011
    Messages : 71
    Par défaut
    Bonjour,

    Je ne comprends pas trop ce que tu essayes de faire tu mets du texte dans ton fichier et après tu essayes de les convertir en structures Point.
    ça ne peux pas marcher. Pour que ça fonctionne il aurait fallu sauvegarder (donc écrire) dans le fichier des structures Point (depuis ton code) ce qui n'est pas le cas.

    Il y a pleins d'autres problème avec ce code de toute façon comme l'initialisation de type long à NULL ?

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Mais l'idée, ca reste malgré tout d'ouvrir le fichier dans le mode dans lequel il a été écrit, et, surtout d'essayer de lire dedans des données cohérentes par rapport aux donnée qui se trouvent dedans

    Par exemple, si tu as une structure de type point proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct Point{
        int x;
        int y;
    };
    et que tu veux pouvoir extraire ce genre de structure depuis un fichier binaire, il faut commencer par ... créer le fichier binaire qui contiendra ces informations.

    Pour ma part, je n'ai aucun fichier (ni binaire, ni texte) qui contienne de telles informations, je vais donc commencer par ... générer une centaine de ces points de manière aléatoire avec une fonction "toute simple":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Point createPoint(){
        static std::random_device rd;
        static std::mt19937 gen(rd());
        std::uniform_int_distribution<> dis(0,10000);
        Point p;
        p.x=dis(gen);
        p.y=dis(gen);
        return p;
    }
    Par facilité, je vais surcharger l'opérateur << pour obtenir un affichage (lisible par l'humain) cohérent sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    std::ostream & operator <<(std::ostream & ofs, Point const & p){
        ofs<<"\tx: "<<p.x<<"\n"
           <<"\ty: "<<p.y<<"\n";
           return ofs;
    }
    Comme je prévois de générer un fichier binaire à partir des points que j'aurai créé de manière aléatoire, je prévois tout de suite la fonction qui permettra de enregistrer le contenu d'un tableau de point sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void saveAsBinary(std::vector<Point> const & tab){
        std::ofstream ofs("points.dat", std::ios::binary);
        ofs.write(reinterpret_cast<const  char *>(&tab[0]), sizeof(Point)*tab.size());
    }
    (oui, je "triche un peu" en écrivant directement un nombre de byte qui correspond au produit du nombre de points créés et de la taille d'un point, en partant du premier élément du tableau, mais c'est tout à fait juste comme logique )

    Et, comme, après, je voudrai pouvoir vérifier si mon fichier binaire contient bien les informations que j'espère, je crée une dernière fonction qui me permet d'enregistrer les points que j'ai créé sous la forme d'un fichier binaire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void saveAsText(std::vector<Point> const & tab){
        std::ofstream ofs("allPoints.txt");
        size_t count{1};
        for(auto const & p:tab){
            ofs<<count<<":\n"
               <<p;
            ++count;
        }
    }
    Maintenant que j'ai tout ce qu'il faut, je peux générer ma centaine de point aléatoires, avec la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main(){
        std::vector<Point> tab;
        for(int i=0;i<100; ++i){
            auto p=create();
            std::cout<<"Point "<<i<<":\n"<<p;
            tab.push_back(p);
        }
        saveAsText(tab);
        saveAsBinary(tab);
    }
    Après compilation, l'exécution devrait provoquer une sortie proche de
    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
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    ./a.out 
    Point 0:
            x: 4054
            y: 9239
    Point 1:
            x: 3447
            y: 6644
    Point 2:
            x: 3758
            y: 5826
    Point 3:
            x: 993
            y: 7941
    Point 4:
            x: 1372
            y: 9032
    Point 5:
            x: 1947
            y: 4897
    Point 6:
            x: 5472
            y: 4349
    Point 7:
            x: 5709
            y: 1311
    Point 8:
            x: 6965
            y: 7578
    Point 9:
            x: 7733
            y: 5213
    Point 10:
            x: 9428
            y: 8452
    Point 11:
            x: 5480
            y: 6643
    Point 12:
            x: 9599
            y: 9449
    Point 13:
            x: 6612
            y: 9135
    Point 14:
            x: 6101
            y: 9019
    Point 15:
            x: 3167
            y: 1547
    Point 16:
            x: 2667
            y: 4669
    Point 17:
            x: 9866
            y: 2061
    Point 18:
            x: 4499
            y: 3247
    Point 19:
            x: 6602
            y: 4501
    Point 20:
            x: 5713
            y: 3547
    Point 21:
            x: 955
            y: 8923
    Point 22:
            x: 3889
            y: 117
    Point 23:
            x: 2149
            y: 7567
    Point 24:
            x: 9552
            y: 236
    Point 25:
            x: 9346
            y: 2217
    Point 26:
            x: 1573
            y: 6559
    Point 27:
            x: 6758
            y: 6239
    Point 28:
            x: 3503
            y: 4612
    Point 29:
            x: 6671
            y: 5073
    Point 30:
            x: 566
            y: 73
    Point 31:
            x: 181
            y: 1307
    Point 32:
            x: 2359
            y: 2155
    Point 33:
            x: 2001
            y: 3760
    Point 34:
            x: 6768
            y: 8472
    Point 35:
            x: 58
            y: 5786
    Point 36:
            x: 7836
            y: 4070
    Point 37:
            x: 9930
            y: 8179
    Point 38:
            x: 7791
            y: 9580
    Point 39:
            x: 5177
            y: 4036
    Point 40:
            x: 2908
            y: 5021
    Point 41:
            x: 2609
            y: 225
    Point 42:
            x: 5382
            y: 6020
    Point 43:
            x: 6331
            y: 1141
    Point 44:
            x: 7009
            y: 1425
    Point 45:
            x: 769
            y: 9252
    Point 46:
            x: 9302
            y: 1011
    Point 47:
            x: 7183
            y: 7044
    Point 48:
            x: 9650
            y: 7446
    Point 49:
            x: 3427
            y: 3870
    Point 50:
            x: 3393
            y: 142
    Point 51:
            x: 3152
            y: 2898
    Point 52:
            x: 7574
            y: 8556
    Point 53:
            x: 4236
            y: 3203
    Point 54:
            x: 4494
            y: 4465
    Point 55:
            x: 2042
            y: 4929
    Point 56:
            x: 9227
            y: 1202
    Point 57:
            x: 5731
            y: 4907
    Point 58:
            x: 2302
            y: 2431
    Point 59:
            x: 721
            y: 1881
    Point 60:
            x: 5546
            y: 2563
    Point 61:
            x: 6409
            y: 8916
    Point 62:
            x: 103
            y: 1672
    Point 63:
            x: 8963
            y: 6013
    Point 64:
            x: 2842
            y: 718
    Point 65:
            x: 8807
            y: 5513
    Point 66:
            x: 9707
            y: 8924
    Point 67:
            x: 5921
            y: 5988
    Point 68:
            x: 7584
            y: 136
    Point 69:
            x: 6512
            y: 882
    Point 70:
            x: 6853
            y: 2222
    Point 71:
            x: 1966
            y: 6532
    Point 72:
            x: 5088
            y: 491
    Point 73:
            x: 1543
            y: 3459
    Point 74:
            x: 5445
            y: 6507
    Point 75:
            x: 4708
            y: 6644
    Point 76:
            x: 9416
            y: 3312
    Point 77:
            x: 5278
            y: 4067
    Point 78:
            x: 2365
            y: 226
    Point 79:
            x: 2518
            y: 8485
    Point 80:
            x: 2925
            y: 5230
    Point 81:
            x: 2445
            y: 4698
    Point 82:
            x: 63
            y: 8574
    Point 83:
            x: 6335
            y: 9245
    Point 84:
            x: 6326
            y: 6617
    Point 85:
            x: 1622
            y: 3906
    Point 86:
            x: 7756
            y: 6393
    Point 87:
            x: 4782
            y: 8107
    Point 88:
            x: 5625
            y: 5818
    Point 89:
            x: 8485
            y: 3173
    Point 90:
            x: 4779
            y: 4384
    Point 91:
            x: 2906
            y: 5860
    Point 92:
            x: 2625
            y: 7431
    Point 93:
            x: 8680
            y: 2463
    Point 94:
            x: 8589
            y: 4875
    Point 95:
            x: 1831
            y: 1643
    Point 96:
            x: 9631
            y: 2399
    Point 97:
            x: 7433
            y: 2058
    Point 98:
            x: 3744
            y: 3479
    Point 99:
            x: 5110
            y: 764
    Mais, surtout, elle aura provoqué la création d'un fichier texte nommé allPoints.txt dont le contenu est sensiblement similaire à la sortie (en mode texte) et celle d'un fichier binaire nommé points.dat.

    (notes que les points sont générés de manière aléatoire, si bien que tant la sorite "console" que le contenu des deux fichiers peut varier énormément de ton coté par rapport à ce que je montre ici )

    N'essaye pas d'ouvrir points.dat avec ton éditeur de textes plats favori, car, au mieux, cela ne fonctionnera pas; au pire, tu n'obtiendra aucune information cohérente si ton éditeur de texte accepte de l'ouvrir.

    Pour observer (sans passer par la programmation, s'entend) le contenu de ce fichier, tu devrais te tourner vers un éditeur hexadécimal (je suis sous debian, j'utilise ghex; sous windows, il en existe un grand nombre, à toi de choisir celui qui te convient ), et ca va ressembler à ceci:Nom : ghex.png
Affichages : 622
Taille : 75,4 Ko

    Si tu compare les bonnes valeurs (un int utilise traditionnellement 4 bytes!!!) avec le contenu du fichier allPoints.txt, tu constatera que ce sont effectivement les valeur x, puis y qui ont été écrites pour chacun des points, dans l'ordre dans lequel ils apparaissaient dans le tableau

    Maintenant, si tu veux travailler (par programmation s'entend) sur les données contenues dans les différents fichier, nous pouvons créer une fonction pour lire le fichier binaire sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    std::vector<Point> readFromBinary(){
        std::ifstream ifs("points.dat", std::ios::binary);
        if(!ifs)
            throw std::runtime_error("unable to open binary file");
        std::vector<Point> tab;
        while(ifs){
            Point p;
            ifs.read(reinterpret_cast<char *>(&p), sizeof(Point));
            tab.push_back(p);
        }
        return tab;
    }
    Pour pouvoir lire le contenu du fichier texte, je vais également surcharger l'opérateur >> (notes que j'aurais du être beaucoup plus rigoureux pour ce faire, mais cette forme fait malgré tout le taf, étant donné que je sais que le fichier présente le format souhaité ) sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    std::istream & operator >>(std::istream & ifs, Point & p){
        char sep;
        int count;
        ifs>>count>>sep>>sep>>sep>>p.x
           >>sep>>sep>>p.y;
        return ifs;
    }
    Grâce à cet opérateur, je peux créer une fonction qui lit l'ensemble du fichier texte et qui renvoie un tableau de points sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    std::vector<Point> readFromText(){
        std::ifstream ifs("allPoints.txt");
        if(!ifs)
            throw std::runtime_error("unable to open text file");
        std::vector<Point> tab;
        while(ifs){
            Point p;
            ifs>>p;
            tab.push_back(p);
        }
        return tab;
    }
    Et comme je vais vouloir comparer le contenu de ce que j'ai lu dans le fichier binaire et celui de ce que j'ai lu dans le fichier texte, je vais également surcharger l'opérateur de comparaison == pour comparer deux points sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    bool operator == (Point const & p1, Point const & p2){
        return p1.x == p2.x && p1.y==p2.y;
    }
    Une fois que j'ai tout cela, je pourrai lire le contenu des deux fichiers (les récupérer dans des tableaux de points différents) et les comparer pour voir si j'obtiens bel et bien les même donnée sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int main(){
        auto t1=readFromBinary();
        auto t2=readFromText();
        if(t1==t2)
            std::cout<< "files have the same contents\n";
        else
            std::cout<<"file contents are different\n";
        return 0;
    }
    Si je compile ce code et que je l'exécute, j'obtiens bel et bien la sortie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ./a.out 
    files have the same contents
    ce qui me confirme non seulement que j'ai écrit les mêmes informations dans le fichier binaire que dans le fichier texte, mais aussi que j'ai pu extraire ces informations de manière cohérente à partir des deux fichiers.

    D'ailleurs, si tu ouvre alPoint.txt avec ton éditeur de textes favori (car cela fonctionne pour lui), que tu modifie la valeur de x (ou de y) d'un seul point, quel qui'il soit, et que tu sauvegarde la modification, une nouvelle exécution du programme provoquera la sortie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ./a.out 
    file contents are different
    Mais, bien sur, il ne sert à rien de vouloir créer des points à partir d'un fichier qui contient ... des notes d'étudiants (ou inversement), tout comme il ne sert à rien de vouloir utiliser le format binaire pour lire un fichier qui a été écrit au format texte (et inversement).

    Je t'ai expliqué, dans mon intervention précédente que
    Citation Envoyé par koala01
    Le mode d'ouverture ne nous permet que de changer la manière d'interpréter les différents bytes qui composent le fichier
    Je n'ai, visiblement, pas été assez clair sur ce coup et je m'en excuse, mais il va de soi que, pour que l'interprétation que l'on va faire des différents bytes qui compose le fichier lors de la lecture ait "un minimum de sens", il faut forcément que le fichier ait été écrit en utilisant la même interprétation.

    C'est le même principe que si je t'écrivais une lettre en anglais: si tu connais l'anglais et que tu sais que tu lis un texte en anglais, tu devrais arriver à la comprendre. Mais, si tu ne connais que le français ou que tu crois que je t'ai écrit la lettre en français, ma lettre n'aura absolument aucun sens pour toi, parce que... tu ne reconnaîtra pas les différents termes que j'aurai utilisés.

    La grosse différence entre toi et un ordinateur, c'est que tu as un cerveau et un certain libre arbitre: même si tu crois que j'ai écrit la lettre en français, il suffira que tu lise une seule phrase pour que tu en vienne à la conclusion que
    non, cette lettre n'est décidément pas écrite en français
    Et, dés que tu en seras arrivé à cette conclusion, elle t'amènera à une autre conclusion qui est
    par contre, cette phrase me dit quelque chose si la lettre est écrite en anglais
    Si bien que tu entrera "automatiquement" dans un processus de traduction de la lettre (au besoin en passant par un service de traduction )

    Quant à l'ordinateur, c'est juste un "brave petit soldat", qui saute sans poser de question quand on lui dit de sauter, qui n'a ni cerveau, ni libre arbitre : Si on lui a dit de lire les informations sous une certaine forme (en mode binaire, par exemple), il va faire ce qu'on lui dit, même si ce qu'il lit n'a aucun sens. Notes que c'est normal, vu que pour lui ce qu'il lit dans un fichier n'a jamais le moindre sens
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 412
    Par défaut
    Merci pour ta réponse, c'est effectivement plus claire avec la comparaison français / anglais. également le faite que de savoir comment il a été écrit permet de le lire.

    Il n'y a que le compilateur qui fait office de traducteur, seulement si le code doit être interpréter comme binaire et donc exécutable.

    Mai comment je détermine dans quel mode le fichier a été écrit, et donc dans quelle mode je peux l'ouvrir (text ou binaire), car utiliser un dé-compilateur pour lire le binaire cela me semble pas très pratique et de tout façons pas complétement lisible.
    Il en va autrement quand il s'agis d'un fichier texte évidement.

    il y a un truc ou j'ai un peux de mal a suivre, un binaire n'est pas un fichier texte.
    La ou la confusion règne c'est que de mon point de vue je ne cherche pas a en traduire le contenu, mai a obtenir les données brut.
    A un moment donner il faut bien stoquer l'information sous ça forme que supporte le matériel, c' est donc sous la forme brut que je cherche à en lire le contenu.

    L'idée est ensuite de pouvoir en obtenir une forme numérique quoi qu'il puisse contenir. sa peut donc celons le résulta obtenus nécessite une traduction pour obtenir la forme numérique, c' est j'espérai obtenir avec ouverture mode binaire.

    Je pense que ce qui ce rapproche le mieux dans ce contexte est d'obtenir un clef d'un fichier grace a un MD5sum https://fr.wikipedia.org/wiki/Md5sum
    Seulement sans ce servir d'un hachage qui dans ce cas de figure sort du context.

    Ce dernier mode de fonctionnement doit bien lire les donnée et en calculer la clé. fait-il une différence entre chaque fichier en changeant du mode texte aux mode binaire a la volée?


    Il y a pleins d'autres problème avec ce code de toute façon comme l'initialisation de type long à NULL ?
    NULL dans ce cas de figure signifie que la variable est vide, tout autre valeur donne une valeur a sont contenu. comme ici je cherchai a savoir si il y avais un souci avec une valeur présente, c 'était donc le seul moyen.

  8. #8
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par panthere noire Voir le message
    Mai comment je détermine dans quel mode le fichier a été écrit, et donc dans quelle mode je peux l'ouvrir (text ou binaire), car utiliser un dé-compilateur pour lire le binaire cela me semble pas très pratique et de tout façons pas complétement lisible.
    Ben, ca, c'est à toi de décider, en fonction de différents facteurs, de la manière dont tu veux écrire le fichier... Et, par conséquent, de la manière qu'il faudra utiliser pour le lire

    A moins que tu ne veuille ouvrir un type bien spécifique de fichier (par exemple : une image, une video, une musique ou que sais-je) et, dans ce cas, il faut te renseigner sur le format des informations que le fichier contient, et t'y tenir
    Citation Envoyé par panthere noire Voir le message
    il y a un truc ou j'ai un peux de mal a suivre, un binaire n'est pas un fichier texte.
    Non, en effet...
    Citation Envoyé par panthere noire Voir le message
    La ou la confusion règne c'est que de mon point de vue je ne cherche pas a en traduire le contenu, mai a obtenir les données brut.
    Dans ce cas, le plus facile est -- peut-être -- d'ouvrir le fichier en binaire et d'en extraire l'ensemble des bytes qui le composent sans essayer de les interpréter de quelque manière que ce soit.

    C'est le mode d'ouverture et d'extraction qui marchera toujours

    Par la suite, il faudra déterminer quelles données sont écrites sous quelle forme, de manière à pouvoir interpréter les différents bytes que tu auras extrait, et ca, ca risque de ne pas être coton
    Citation Envoyé par panthere noire Voir le message
    A un moment donner il faut bien stoquer l'information sous ça forme que supporte le matériel, c' est donc sous la forme brut que je cherche à en lire le contenu.
    Stocker l'information en mémoire, tant que tu n'essaye pas d'interpréter les informations que tu stockes, ca, ce n'est pas un problème:
    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
    int main(){
        std::vector<std::byte> tab;
        std::ifsteam ifs(nom_du_fichier, std::ios::binary);
        if(! ifs)
            throw std::runtime_error("unable to open file");
        std::byte temp;
        /* y a moyen de faire plus rapide, mais ca fera l'affaire */
        while(ifs){
            ifs.read(reinterpret_cast<char*>(&temp), sizeof(std::byte);
            tab.push_back(temp);
        }
        /* tab contient exactement ce que ton fichier contient 
         * tu peux utiliser le contenu de tab ici
         */
    }
    produira l'effet escompté
    Citation Envoyé par panthere noire Voir le message
    L'idée est ensuite de pouvoir en obtenir une forme numérique quoi qu'il puisse contenir. sa peut donc celons le résulta obtenus nécessite une traduction pour obtenir la forme numérique, c' est j'espérai obtenir avec ouverture mode binaire.
    Comme je l'ai dit : pour pouvoir interpréter les données qu'un fichier contient, tu dois savoir... comment ces données ont été écrite, sous quelle forme et dans quel ordre
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 412
    Par défaut
    Merci pour toutes tes précisions.

    j'ai une erreur de compilation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error: 'byte' is not a member of 'std'|


    malgrer l'option c++17 cochée. j'utilise code block ver 17.12 ,

    Je devrai peut être faire un autre poste peut être pour ce problème ?

  10. #10
    Membre expérimenté
    Homme Profil pro
    Développeur
    Inscrit en
    Août 2011
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Août 2011
    Messages : 71

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 412
    Par défaut
    euh non

    meme message.

    les déclarations testées.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <cstddef>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
        std::byte temp;
    error: 'byte' is not a member of 'std'|
    Merci pour ta réponse

  12. #12
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Alors, c'est soit
    • que tu ne compile pas en C++17
    • que ton compilateur ne supporte pas encore entièrement la norme

    (je pencherais par défaut pour la première solution )
    Voici la doc pour std::byte

    Mais, quelle que soit la raison, tu peux sans gros problème remplacer std::byte par /* unsigned */ char partout dans le code, cela fonctionnera également

    D'ailleurs si tu utilise char et non unsigned char, tu n'auras même plus besoin du reinterpret_cast
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. ouvrir un fichier en mode binaire ?
    Par rimas2009 dans le forum Général Java
    Réponses: 1
    Dernier message: 19/05/2009, 11h57
  2. Ouvrir un fichier en mode binaire.
    Par _christophe_ dans le forum Général Python
    Réponses: 20
    Dernier message: 14/05/2008, 06h28
  3. Ouvrir un fichier en mode lecture
    Par marwa_rades dans le forum Assembleur
    Réponses: 1
    Dernier message: 29/12/2006, 14h51
  4. 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
  5. Réponses: 4
    Dernier message: 04/11/2005, 09h04

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