web-dev-qa-db-fra.com

Lecture binaire iStream octet d'octet

J'essayais de lire un octet de fichier binaire par octet à l'aide d'une ifstream. J'ai utilisé des méthodes Istream comme Get () avant de lire des morceaux entiers d'un fichier binaire à la fois sans problème. Mais ma tâche actuelle se prête à aller d'octet par octet et à s'appuyer sur la mise en mémoire tampon dans l'IO-System pour la rendre efficace. Le problème est que j'ai semblé atteindre la fin du fichier plusieurs octets plus tôt que je ne le devrais. J'ai donc écrit le programme de test suivant:

#include <iostream>
#include <fstream>

int main() {
    typedef unsigned char uint8;
    std::ifstream source("test.dat", std::ios_base::binary);
    while (source) {
        std::ios::pos_type before = source.tellg();
        uint8 x;
        source >> x;
        std::ios::pos_type after = source.tellg();
        std::cout << before << ' ' << static_cast<int>(x) << ' '
                  << after << std::endl;
    }
    return 0;
}

Ceci décharge le contenu de test.dat, un octet par ligne, montrant la position de fichier avant et après.

Bien sûr, si mon fichier se trouve avoir la séquence de deux octets 0x0d-0x0a (qui correspond au retour du chariot et à l'alimentation en ligne), ces octets sont ignorés.

  • J'ai ouvert le flux en mode binaire. Ne devrait-il pas l'empêcher d'interpréter des séparateurs de ligne?
  • Les opérateurs d'extraction utilisent-ils toujours le mode texte?
  • Quelle est la bonne façon de lire octets par octets d'un binaire Istream?

MSVC++ 2008 sous Windows.

23
Adrian McCarthy

Les >> Les extracteurs sont pour une entrée formatée; Ils ignorent l'espace blanc (par défaut). Pour une entrée non formatée de caractères unique, vous pouvez utiliser istream::get() (retourne un int, soit EOF si la lecture échoue, ou une valeur dans la plage [0, Uchar_max]) ou istream::get(char&) (met le personnage lu dans l'argument, renvoie quelque chose qui convertit sur bool, vrai si la lecture réussit, et false si elle échoue.

21
James Kanze

il y a une fonction de membre Lecture () dans laquelle vous pouvez spécifier le nombre d'octets.

5
stefaanv

Pourquoi utilisez-vous une extraction formatée plutôt que .read()?

Comme les autres ont mentionné, vous devez utiliser istream::read() . Mais, si vous devez utiliser une extraction formatée, considérez std::noskipws .

2
Robᵩ