2015-04-20 32 views
5

Ho un dispositivo che mi invia dati binari di tipo uint32_t. Voglio salvare i dati in un file binario. Ecco il mio codice:Scrittura di file binari in C++

#include<iostream> 
#include<fstream> 
#include <cstdlib> 

using namespace std; 

int main() 
{ 
    ofstream myFile ("data2.bin", ios::out | ios::binary); 

    bool buffer[32]; 

    for (int k = 0; k<100; k++) 
    { 
     for (int i = 0; i<32;i++) 
    { 
    buffer[i] = (bool)rand()%2; 
    } 
    myFile.write ((char*)&buffer, 32); 
    } 
    myFile.close(); 
} 

Funziona, ma la dimensione del file è 3.2 kB, non 0.4 kB. Inoltre, quando provo a leggere i dati dal file (i dati prodotti dal mio dispositivo), ottengo risultati strani, non nel formato descritto nel manuale. Certo, ci sono più dati di quanto mi aspetti.

Cosa sto sbagliando?

+7

Stai scrivendo 100 volte 32 byte. Perché pensi che dovrebbe essere 0.4kB? Mi sto perdendo qualcosa? --- Oh, capisco ... – nickie

+0

32 bool è normalmente 32 byte. unit32 è un tipo di dati a 32 bit che è 4 byte in un byte da 8 bit. – NathanOliver

+0

Quindi, qual è il modo più sicuro per scrivere uint_32t in un file binario? – user2738748

risposta

9

A bool accetta un byte. Controlla sizeof(bool) e lo troverai pari a 1. Quindi la matrice è lunga 32 byte e la stai scrivendo 100 volte, quindi 3.2kB.

Se si desidera memorizzare un array di bit, è necessario utilizzare qualcosa di diverso da un array di bool. Si dispone di un certo numero di opzioni:

  1. utilizzare un array di byte, interi, o qualsiasi cosa la cui dimensione si sa, e girare in modo esplicito sui bit che si desidera. Quindi, memorizzare la matrice.

    #include <iostream> 
    #include <fstream> 
    #include <cstdlib> 
    #include <cstdint> 
    
    using namespace std; 
    
    int main() 
    { 
        ofstream myFile ("data2.bin", ios::out | ios::binary); 
    
        uint32_t buffer; 
    
        for (int k = 0; k<100; k++) { 
        buffer = 0; 
        for (int i = 0; i<32; i++) { 
         buffer <<= 1; 
         buffer |= (bool)(rand()%2); 
        } 
        myFile.write((char*) &buffer, sizeof(buffer)); 
        } 
        myFile.close(); 
        return 0; 
    } 
    

    In realtà, se si dispone già di una serie di uint32_t per cominciare, quindi non è necessario il ciclo e si può semplicemente memorizzare direttamente l'array. Utilizzare la riga esatta in alto, dove buffer è l'array uint32_t.

  2. Utilizzare uno vector<bool> o preferibilmente uno bitset. Entrambi sono ottimizzati e usano un bit per elemento.

    #include <iostream> 
    #include <fstream> 
    #include <cstdlib> 
    #include <bitset> 
    
    using namespace std; 
    
    int main() 
    { 
        ofstream myFile ("data2.bin", ios::out | ios::binary); 
    
        bitset<32> buffer; 
    
        for (int k = 0; k<100; k++) { 
        for (int i = 0; i<32; i++) { 
         buffer[i] = (bool)(rand()%2); 
        } 
        myFile.write((char*) &buffer, 32/8); 
        } 
        myFile.close(); 
        return 0; 
    } 
    

Naturalmente, in entrambi i casi, è byte di uscita al file. Nel secondo caso, il numero di bit deve essere un multiplo di 8.