Saving a vector to a binary file

Discussion in 'Programmer's Corner' started by mentaaal, Nov 27, 2008.

  1. mentaaal

    Thread Starter Senior Member

    Oct 17, 2005
    451
    0
    Hey guys, I am having a c++ problem and i cant find any info on how to solve it.
    I am nearly finished my last c++ assignement and the problem i am having is successfully saving and opening a file.
    I have to make a student database. What i have done is create vector of structures.
    I need to know how to save a vector to a binary file and then retrieve it again. The code i have used compiles but the program crashes when i try to do anything with it after opening it again, probably because the size of the vector wasn't found properly.

    I am writing to the file like this:
    file.read(reinterpret_cast<char *>(&(students)),sizeof(students));
    where students is the vector in question

    I am reading from the file like this:
    file.read(reinterpret_cast<char *>(&(students)),sizeof(students));

    I have an integer which i read in before reading the vector and write before writing the vector which i am able to do successfully.

    Thanks,

    Greg
     
  2. Mark44

    Well-Known Member

    Nov 26, 2007
    626
    1
    Maybe you copied the wrong line of your source code. You said you were writing to the file, but you have called read in the line above.

    From your description, students is a struct, and the array (vector) consists of structs of type students. Now assuming you meant to call file.write(), the second arg is probably wrong. As it is, it evaluates to the size of a single struct. What you want is the total number of bytes to write of all the elements in your array, not just the number of bytes in one array element. Assuming there are 10 student records in the array (indexed from 0 through 9), this code might be what you want:
    Code ( (Unknown Language)):
    1.  
    2. file.write(reinterpret_cast<char *>(&(students)), 10 * sizeof(students));
    3.  
    Of course it would be better not to hard-code the number of elements as I did. Here's a version that uses a variable that represents the number of student records.
    Code ( (Unknown Language)):
    1.  
    2. file.write(reinterpret_cast<char *>(&(students)), size * sizeof(students));
    3.  
    Hope this helps!
     
  3. mentaaal

    Thread Starter Senior Member

    Oct 17, 2005
    451
    0
    Hey Mark, thanks for the reply,
    Well no the vector is called students and contains structs of type student.
    I am guessing that you cant just write the vector to the file by name you have have to get the sizeof the amount of elements in the array right?

    Cant test that this morning but i will let you know how it goes a bit later.

    Thanks!
     
  4. mentaaal

    Thread Starter Senior Member

    Oct 17, 2005
    451
    0
    Hooray! I got it!
    Thanks for the help Mark, with your help and some more googling i got it going. For your own interest i read in the file like this:
    Code ( (Unknown Language)):
    1. if (records != 0)
    2.         {
    3.             cout << "successfully read in records and its value is " << records << endl;
    4.             students.resize(records);
    5.             //for (int i  = 0; i < records; i++)
    6.             for(int i = 0; i < records; i++)
    7.                 file.read(reinterpret_cast<char *>(&(students.at(i))),sizeof(student));
    8.                 //file.read(reinterpret_cast<char *>(&(students.at(i))),sizeof(struct student));
    9.            
    10.         }
    and wrote the file like this:
    Code ( (Unknown Language)):
    1. file.write(reinterpret_cast<char *>(&records),sizeof(records));
    2.             for(int i = 0; i < records; i++)
    3.                 file.write(reinterpret_cast<char *>(&students.at(i)),sizeof(student));
    4.             file.close();
     
  5. Mark44

    Well-Known Member

    Nov 26, 2007
    626
    1
    Glad to be of help. With regard to your question, I think you could probably write the whole thing with one call to write, provided that you give it the right size in the second argument. The way read() and write() work is that you give them a starting address and the number of bytes to read/write. The approach you came up with goes through the array and reads/writes one student record at a time, which is certainly a reasonable approach.

    I take it you are now in Ireland. I seem to remember that your were in the U. S. South before, like Alabama or Mississippi. Is my recollection correct?
    Mark
     
  6. mentaaal

    Thread Starter Senior Member

    Oct 17, 2005
    451
    0
    :) Nope I am actually South African and have been living here for 8 years now, I just hadn't updated my profile before.

    With regard to your last comment, I tried doing it that way but the program keeps crashing....

    I read the file like this:
    Code ( (Unknown Language)):
    1. students.resize(records);
    2.             //for(int i = 0; i < records; i++)
    3.                 file.read(reinterpret_cast<char *>(&(students)),sizeof(student)*records);
    This is based upon records which is read in first.
    Then at the end of the program, the vector is written to file like this:

    Code ( (Unknown Language)):
    1. file.write(reinterpret_cast<char *>(&records),sizeof(records));
    2.             //for(int i = 0; i < records; i++)
    3.                 file.write(reinterpret_cast<char *>(&(students)),sizeof(student)*records);
    It compiles but crashes upon program exit...

    Its not too big a deal though because i have it going at least the other way so i'm happy!
     
    Last edited: Nov 28, 2008
Loading...