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 :

probléme lecture de fichier binaire octer par octet


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Juillet 2004
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 2
    Points : 1
    Points
    1
    Par défaut probléme lecture de fichier binaire octer par octet
    Bonjour,
    je souhaite lire un fichier binaire octet par octet et afficher les bits puis les convertir.
    le programme marche bien avec le seul souci qu'il y'a une position du fichier (octet) qui n'est pas lu.
    A quoi est ce du ? j'ai reparcouru de long en large mais je ne vois pas la potentielle cause ou solution. Merci de votre assistance.

    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
    15
    16
    #include<fstream>
    #include <iostream>
    using namespace std;
        int main()
        {
            //char str;
            short int str;
            int n=0;
            fstream file_op("hlr",ios::in|ios::binary);
            while(file_op >> str)
            {
            cout <<"octet n " << n; cout << ":";
            cout << str ; cout << "\n";
            n++;
     
                  }
    la premiére octet qu'il saute se trouve au numéro 46; il le saute sans signaler une quelconque erreur

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut, et bienvenue sur le forum.

    Déjà, il faut savoir que le "bon" type à utiliser lorsqu'il s'agit de lire un byte (car le terme octet est par trop... restrictif), est bel et bien le caractère, et plus précisément le caractère non signé (unsigned char).

    Ensuite, il est bon de se rappeler que l'opérateur >> est un opérateur sur les flux formatés, c'est à dire, typiquement, sur les flux utilisant le mode "texte" (par opposition au mode binaire, dans lequel tu ouvre ton fichier).

    Cet opérateur pose entre autres le problème qu'il considère chaque octet lu comme... un caractère.

    Or, tous les caractères ayant une valeur inférieure à 31 sont des caractères non affichables (parmi lesquels on trouve le '\0', la tabulation, la "cloche" (BELL), le retour à la ligne '\n' et tant d'autres) et, lorsqu'un flux est traité de manière formatée, il est donc "logique" de voir que certains de ces caractères sont, tout simplement, ignorés (ou du moins interprétés différemment).

    Tout cela pour en venir au fait que, typiquement, si tu dois effectuer une lecture binaire d'un fichier, ce n'est pas l'opérateur >> que tu dois utiliser, mais bien la fonction read(), membre de la classe ifstream.

    Tu trouvera un exemple de code dans la réponse de la FAQ traitant de la lecture et de l'écriture de fichiers binaires

    Ensuite, il me semble important de signaler que l'interprétation qui sera faite des valeurs lues dépendra essentiellement du type que tu envisage d'utiliser lors de la lecture.

    Ainsi, si ton objectif est, réellement, de récupérer les valeurs sous la forme d'un byte, le type que tu dois utiliser est bel et bien le caractère, et plus précisément le caractère non signé (unsigned char), car c'est le type par excellence dont on a l'absolue certitude qu'il représente... un byte (alors que l'on ne peut partir de strictement aucun a priori sur la taille des autres types primitifs, hormis qu'ils sont tous composés d'un nombre entier de byte et qu'il respectent la logique (unsigned) char <= (unsigned)short <= (unsigned) int <= (unsigned) long <= (unsigned) long long )

    Par chance, il existe un valeur (déclarée dans le fichier d'ent-tête limits.h) qui permet de connaitre le nombre de bits utilisé par un (unsigned) char: CHAR_BIT.

    Cependant, le fait d'utiliser le byte comme type pour la lecture implique, fatalement, que, lors de l'affichage, il sera considéré comme... un caractère, avec, de nouveau, les problèmes liés aux 32 fameuses valeurs représentant des caractères non affichables (et au 126 autres pouvant représenter des signes plus ou moins "cabalistiques").

    Il faut donc réfléchir à la manière dont tu souhaites que ces valeurs soient affichée, car, tel que ton code est écrit, tu n'obtiens absolument pas l'affichage de tous les bits, mais bien l'affichage de valeurs décimales correspondant aux valeurs représentées par le nombre de bits que tu a lu.

    Si l'idée est d'afficher réellement l'état de chacun des bits des valeurs lues, il faut passer par une classe particulière nommée le bitset, qui n'est, pour faire simple, rien de plus qu'un "tableau de bits".

    Si, par contre, l'idée est d'afficher ces valeurs de manière plus ou moins lisible, il faudra convertir la valeur du caractère en une valeur explicitement numérique (de type unsigned int, par exemple) et le cas échéant préciser que tu souhaite l'affichage hexadécimal comme "option de formatage" du flux.

    Ainsi, ton programme pourrait prendre 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
    13
    14
    15
    16
    17
    18
    19
    20
    #include <bitset> // pour pouvoir utiliser la classe ... bitset
    #include <limits.h> // pour pouvoir disposer de la constante CHAR_BIT
    #include <iostream> // pour pouvoir disposer de cout
    #include <fstream> // pour pouvoir disposer de... ifstream
    int main()
    {
        std::ifstream ifs("fichier.bin",std::ios::binary);
        char c;
        while(ifs.read(c,1))
        {
            /* pour l'affichage binaire, nous passons par un bitset */
            std::bitset<CHAR_BIT> bs(c);
            std::cout<<"binaire : "<<bs;
            /* pour provoquer l'affichage sous la forme décimale */
            std::cout<<" decimal : "<<(int)c;
            /* pour provoquer l'affichage sous forme hexadécimale */
            std::cout<<" hexadecimal : 0x"<<std::hex<<(int)c<<std::endl;
        }
        return 0;
    }
    Tu trouvera plein d'infos sur le formatages des sorties en lisant la question qui s'y rapporte de la FAQ

    De manière générale, tu devrais envisager de faire un tour du coté de la FAQ, et plus précisément du coté de la section relative à la manipulation des fichers... Elle devrait répondre à la plupart des questions que tu pourrais te poser sur le sujet, et même sans doute à certaines questions qui ne te viendraient pas naturellement à l'esprit en débutant
    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
    Nouveau Candidat au Club
    Inscrit en
    Juillet 2004
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Merci
    Bonjour,
    Merci Kaola de ta réponse et des liens interressants qui figurent.
    j'en ai dejà parcouru quelques et ça m'est trés utiles
    cependant , j'ai testé le bout de code que tu as mis mais j'ai quelques msgs d'erreurs suivants au niveau du [ while ifs.read(c,1) ]

    10 C:\cpp\ex_read.cpp invalid conversion from `char' to `char*'
    10 C:\cpp\ex_read.cpp initializing argument 1 of `std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::read(_CharT*, std::streamsize) [with _CharT = char, _Traits = std::char_traits<char>]'

    Je suis en train de chercher la potentielle cause mais si jamais tu saurais la cause, cela me serait useful.
    Merci d'avance.

Discussions similaires

  1. Problème de lecture de fichiers binaires
    Par -Gesicht- dans le forum Débuter
    Réponses: 7
    Dernier message: 05/07/2013, 17h15
  2. Problème lecture de fichier binaire
    Par -N4w4k- dans le forum C#
    Réponses: 3
    Dernier message: 16/02/2013, 22h16
  3. Réponses: 7
    Dernier message: 31/10/2010, 15h39
  4. Lecture d'un fichier binaire ligne par ligne
    Par hacksi dans le forum Langage
    Réponses: 4
    Dernier message: 06/03/2008, 12h08
  5. Réponses: 5
    Dernier message: 26/03/2007, 01h30

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