2017-12-07 2 views
0

Ich habe einen einfachen Vektor von Ints, und ich möchte es in eine Binärdatei schreiben. Zum Beispiel:C++ - Binärdatei - Schreiben von Ints - seltsames Verhalten

#include <fstream> 
#include <vector> 

int main() { 
    std::vector<uint32_t> myVector{5, 10, 15, 20 }; 
    // write vector to bin file 
    std::ofstream outfile("./binary_ints.data", std::ios_base::binary|std::ios::trunc); 
    std::copy(myVector.begin(), myVector.end(), std::ostreambuf_iterator<char>(outfile)); 
    outfile.close(); 
    return 0; 
} 

Dann, wenn ich die Datei "binary_ints.data" in Hex-Modus überprüfen, habe ich dieses:

00000000: 050a 0f14 0a 

Das ist ok !.

jedoch Wenn myVector diese Daten hat:

std::vector<uint32_t> myVector{3231748228}; 

Dann gespeicherte hex ist seltsam:

00000000: 840a 

84 in Hex nicht mit dem Int passen 3231748228.

Was geschieht Hier? Danke.

+2

'std :: copy' transformiert kein Element in mehrere neue Elemente, noch' std :: ostreambuf_iterator'. – chris

+2

Sie hätten etwas experimentieren können, um zu sehen, was passiert, wenn der 'int'-Wert> 255 ist. – PaulMcKenzie

+2

Ich bin neugierig, woher der zusätzliche Zeilenumbruch kommt (außer dem, der tatsächlich Teil der Vektordaten ist). Das Programm sollte nicht nach den Vektordaten schreiben. –

Antwort

3

Das Problem ist, dass jeder Wert in Ihrem std::vector<uint32_t> als char während Ihrer std::copy() Aufruf interpretiert wird. 3231748228 wird in Hex als ‭C0A09084 dargestellt. std::copy() dauert uint32_t Wert, schneidet es auf einzelnes Byte, das 0x84 auf Little-endian Prozessor ist. Nach dem Schreiben des Bytes 0x84 in das Datei-Byte wird 0x0a hinzugefügt, was new line character entspricht.

Eine mögliche Lösung ist ofstream::write() statt std::copy() zu verwenden:

#include <fstream> 
#include <vector> 

int main() { 
    std::vector<uint32_t> myVector{3231748228 }; 
    // write vector to bin file 
    std::ofstream outfile("./binary_ints.data", std::ios_base::binary|std::ios::trunc); 

    outfile.write (
     (char*)(myVector.data()), 
     myVector.size() * sizeof (decltype (myVector)::value_type)); 

    outfile.close(); 
    return 0; 
} 

Beachten Sie die Verwendung von decltype(). Der gleiche Effekt kann durch einfaches Schreiben sizeof (uint32_t) erreicht werden, aber mit decltype() können Sie sicher sein, dass der Code auch dann korrekt bleibt, wenn Sie den Wert myVector ändern.