Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to correctly write vector to binary file in c++?

Tags:

c++

fstream

Thanks to Mats Petersson for the explanation on how to to copy vector to array, it's seems work. Here is the code snipet:

#include <iostream> #include <string.h> #include <vector> #include <fstream>  using namespace std;  class Student   {     private:     char m_name[30];     int m_score;      public:     Student()       {        }     Student(const Student& copy)       {            m_score = copy.m_score;   //wonder why i can use this statment as            strncpy(m_name, copy.m_name, 30); //declare it private       }       Student(const char name[], const int &score)       :m_score(score)       {            strncpy(m_name, name, 30);       }       void print() const       {            cout.setf(ios::left);            cout.width(20);            cout << m_name << " " << m_score << endl;       }       };         int main()       {         vector<Student> student;         student.push_back(Student("Alex",19));         student.push_back(Student("Maria",20));         student.push_back(Student("muhamed",20));         student.push_back(Student("Jeniffer",20));         student.push_back(Student("Alex",20));         student.push_back(Student("Maria",21));       {       Student temp[student.size()];       unsigned int counter;       for(counter = 0; counter < student.size(); ++counter)       {         temp[counter] = student[counter];       }        ofstream fout("data.dat", ios::out | ios::binary);       fout.write((char*) &temp, sizeof(temp));       fout.close();       }        vector<Student> student2;       ifstream fin("data.dat", ios::in | ios::binary);        {         fin.seekg(0, ifstream::end);         int size = fin.tellg() / sizeof (Student);         Student temp2[size];         fin.seekg(0, ifstream::beg);         fin.read((char*)&temp2, sizeof(temp2));         int counter;         for(counter = 0; counter <6; ++counter)         {         student2.push_back(temp2[counter]);         }         fin.close();       }       vector<Student>::iterator itr = student2.begin();       while(itr != student2.end())       {         itr->print();         ++itr;       }       return 0;       } 

But I guest this method will waste huge memory and be cumbersome. Maybe I will consider writing it Mr. with ocelot and other suggestions. Thanks everyone for the answer.

like image 408
dchochan Avatar asked Dec 30 '12 08:12

dchochan


People also ask

Can you do binary search on a vector?

Do note that a binary search only works on a sorted data set. If the user enters non sorted data then you need to sort the vector before you can run a binary search on it. Sometimes using an array will hide off-by-one or other subtle bugs.

What is binary file in C Plus Plus?

It is used to write a given number of bytes on the given stream, starting at the position of the "put" pointer. The file is extended if the put pointer is currently at the end of the file. If this pointer points into the middle of the file, characters in the file are overwritten with the new data.


2 Answers

To store a vector<T> of PODs in a file, you have to write the contents of the vector, not the vector itself. You can access the raw data with &vector[0], address of the first element (given it contains at least one element). To get the raw data length, multiply the number of elements in the vector with the size of one element:

strm.write(reinterpret_cast<const char*>(&vec[0]), vec.size()*sizeof(T)); 

The same applies when you read the vector from the file; The element count is the total file size divided by the size of one element (given that you only store one type of POD in the file):

const size_t count = filesize / sizeof(T); std::vector<T> vec(count); strm.read(reinterpret_cast<char*>(&vec[0]), count*sizeof(T)); 

This only works if you can calculate the number of elements based on the file size (if you only store one type of POD or if all vectors contain the same number of elements). If you have vectors with different PODs with different lengths, you have to write the number of elements in the vector to the file before writing the raw data.

Furthermore, when you transfer numeric types in binary form between different systems, be aware of endianness.

like image 140
Anonymous Coward Avatar answered Sep 21 '22 01:09

Anonymous Coward


You are writing to file the vector structure, not its data buffer. Try change writing procedure to:

 ofstream fout("data.dat", ios::out | ios::binary);  fout.write((char*)&student[0], student.size() * sizeof(Student));  fout.close(); 

And instead of calculation size of vector from file size, it's better write vector size (number of objects) before. In the case you can write to the same file other data.

 size_t size = student.size();  fout.write((char*)&size, sizeof(size)); 
like image 33
ocelot Avatar answered Sep 23 '22 01:09

ocelot