-
std::string to binary
Hello.
Our current assignment in C++ class involves reading/writing strings to file in binary format. Our professor has his own string class which we can use, but I've decided to use std::string. This is my first experience with binary files, so I'm trying to figure out how it works. Here is a small program that I wrote to better understand it:
Code:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
int main(){
string name, take;
cout << "Enter name: ";
cin >> name;
ofstream fout("FFF.dat", ios_base::out | ios_base::binary);
fout.write(reinterpret_cast<char*> (&name), name.size()+name.capacity());
fout.close();
take.reserve(name.capacity());
take.resize(name.length());
ifstream fin("FFF.dat", ios_base::in | ios_base::binary);
if(fin.is_open()){
fin.read(reinterpret_cast<char*> (&take), name.size()+name.capacity());
}
fin.close();
cout << take << endl;
return 0;
}
It seems that it writes the string to file and is able to read it, but if name is larger than 15 chars it crashes after it outputs take. Does anyone know what I'm doing wrong, or if there is a better way to do this? I'm guess that I'm not getting the correct size of the string object, or that there may be virtual functions in string that are causing problems. any suggestions?
-
You can't write directly to a string's contents like that. reinterpret_cast<char*> (&take) does not provide access to the string's internal array. You can read from it, but you have to call data() and use size() for the size:
Code:
fout.write(name.data(), name.size());
The reason it may have worked for 15 characters or less is that some string implementations keep an internal buffer for small strings (that is often 16 characters long), so you were getting lucky. But you cannot rely on that.
Instead of writing to the string, you need to read from the file into an array or vector and then copy that to the string. You have to be able to determine how many bytes you will be reading from the file. This can be done either by writing the size of the string to the file in the first place, or by always writing the same amount of characters. In this simple case you are using the size of name, but that might not work in a larger program. For this example I'll use it, though:
Code:
{
vector<char> take_vec(name.size());
fin.read(&take_vec[0], name.size());
take.assign(take_vec.begin(), take_vec.end());
}
-
Okay, I get it now. Thanks Daved.