67 votes

Existe-t-il des flux de mémoire binaire en C ++?

J'utilise habituellement stringstream d'écrire dans la mémoire de la chaîne. Est-il possible d'écrire sur un char tampon en mode binaire? Considérons le code suivant:

stringstream s;
s << 1 << 2 << 3;
const char* ch = s.str().c_str();

La mémoire à l' ch ressemblera à ceci: 0x313233 - les codes ASCII des caractères 1, 2 et 3. Je suis à la recherche d'une façon d'écrire les valeurs binaires eux-mêmes. C'est, je veux 0x010203 dans la mémoire. Le problème est que je veux être capable d'écrire une fonction

void f(ostream& os)
{
    os << 1 << 2 << 3;
}

Et de décider en dehors de ce type de flux à utiliser. Quelque chose comme ceci:

mycharstream c;
c << 1 << 2 << 3; // c.data == 0x313233;
mybinstream b;
b << 1 << 2 << 3; // b.data == 0x010203;

Des idées?

43voto

KeithB Points 9459

Pour lire et écrire des données binaires dans des flux, y compris des flux de chaîne, utilisez les fonctions membres read () et write (). Alors

 int a(1), b(2), c(3);
stringstream s;
s.write(&a, sizeof(int));
s.write(&b, sizeof(int));
s.write(&c, sizeof(int));
 

Édition: pour que cela fonctionne de manière transparente avec les opérateurs d’insertion et d’extraction (<< et >>), il est préférable de créer un streambuf dérivé qui fait la bonne chose et de le transmettre aux flux que vous voulez utiliser.

3voto

Lukáš Lalinský Points 22537

Eh bien, utilisez simplement des caractères, pas des nombres entiers.

 s << char(1) << char(2) << char(3);
 

3voto

la surcharge de certaines des opérateurs fonctionne plutôt bien. Voici ci-dessous, j'ai choisi de surcharge <= , car il a la même de gauche à droite associativité comme << et a en quelque sorte un regard de près et sentir ...

#include <iostream>
#include <stdint.h>
#include <arpa/inet.h>

using namespace std;

ostream & operator<= (ostream& cout, string const& s) {
    return cout.write (s.c_str(), s.size());
}
ostream & operator<= (ostream& cout, const char *s) {
    return cout << s;
}
ostream & operator<= (ostream&, int16_t const& i) {
    return cout.write ((const char *)&i, 2);
}
ostream & operator<= (ostream&, int32_t const& i) {
    return cout.write ((const char *)&i, 4);
}
ostream & operator<= (ostream&, uint16_t const& i) {
    return cout.write ((const char *)&i, 2);
}
ostream & operator<= (ostream&, uint32_t const& i) {
    return cout.write ((const char *)&i, 4);
}

int main() {
    string s("some binary data follow : ");

    cout <= s <= " (machine ordered) : " <= (uint32_t)0x31323334 <= "\n"
         <= s <= " (network ordered) : " <= htonl(0x31323334) ;
    cout << endl;

    return 0;
}

Il y a plusieurs inconvénients :

  • le nouveau sens de l' <= peut confondre les lecteurs ou conduire à des résultats inattendus :

    cout <= 31 <= 32;
    

    on ne donnera pas le même résultat que

    cout <= (31 <= 32);
    
  • l'endianess n'est pas clairement mentionné lors de la lecture du code, comme illustré dans l'exemple ci-dessus.

  • il est impossible de mélanger tout simplement avec << parce qu'il n'appartient pas à la même groupe de préséance. J'ai l'habitude d'utiliser des parenthèses pour préciser ces comme :

    ( cout <= htonl(a) <= htonl(b) ) << endl;
    

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X