Read from binary to a std::vector

Started by
4 comments, last by Zahlman 14 years, 8 months ago
Hi, normally i use to write some files to a binary files on this way: struct Ex { int a; float b; bool c; }; //... Ex obj; obj.a = 10; obj.b = 5.0f; c = true; ofstream Files("RP.dat",ios::binary | ios::app | ios::out); Files.write(reinterpret_cast<char *>(&obj),sizeof(Ex)); Files.close(); And append new registers to the same file, when i want to open the file, my way to do it is: int size; int numRegisters; Ex *AllReports; ifstream file ("RP.dat", ios::in|ios::binary|ios::ate); size = file.tellg(); numRegisters = size/sizeof(Ex); AllReports = new Ex[numRegisters]; file.seekg (0, ios::beg); file.read (reinterpret_cast<char *>(&AllReports[0]), size ); file.close(); Its a very easy way to load to an array all the file, but i need to use a std::vector, i want to know if there is some way to do it in the same way, i can do it by the hard way with strides byte per byte, but i´m sure there is a better way to do it. Thanks
Advertisement
std::vector holds elements as continuous memory block, same way normal array does, so you can read elements like this:

std::vector<Ex> AllReports(numRegisters);

file.read (reinterpret_cast<char*>(&AllReports[0]), size);

It'll work the same for a std::vector:

std::vector<Ex> reports(num_reports);
file.read(reinterpret_cast<char*>(&reports[0]), num_bytes);

It still has the exact same pitfalls associated with reading and writing structs in this way.
Oh lool, that work´s perfect, i was even looking istream iterator,
but is so simple, is almost the same, i notice that a pointer to
the begin of the vector works too:

file.read (reinterpret_cast<char *>(&*Reports.begin()), size );

Thanks!
Quote:Original post by _Camus_
Oh lool, that work´s perfect, i was even looking istream iterator,
but is so simple, is almost the same, i notice that a pointer to
the begin of the vector works too:

file.read (reinterpret_cast<char *>(&*Reports.begin()), size );

Thanks!


you are actually dereferencing iterator to the first element in the container. another popular way is

file.read (reinterpret_cast<char *>(&Reports.front()), size );

where front() returns reference to first element so that iterator indirection is avoided
They will probably all compile to the same code, but I think an argument can be made that '&vec.front()' is the clearest and most idiomatic form (even though I would personally be most likely to write '&(vec[0])' ^^; ).

This topic is closed to new replies.

Advertisement