How to write an object to file in C++

42,737

Solution 1

You can override operator>> and operator<< to read/write to stream.

Example Entry struct with some values:

struct Entry2
{
    string original;
    string currency;

    Entry2() {}
    Entry2(string& in);
    Entry2(string& original, string& currency)
        : original(original), currency(currency)
    {}
};


istream& operator>>(istream& is, Entry2& en);
ostream& operator<<(ostream& os, const Entry2& en);

Implementation:

using namespace std;

istream& operator>>(istream& is, Entry2& en)
{
    is >> en.original;
    is >> en.currency;
    return is;
}

ostream& operator<<(ostream& os, const Entry2& en)
{
    os << en.original << " " << en.currency;
    return os;
}

Then you open filestream, and for each object you call:

ifstream in(filename.c_str());
Entry2 e;
in >> e;
//if you want to use read: 
//in.read(reinterpret_cast<const char*>(&e),sizeof(e));
in.close();

Or output:

Entry2 e;
// set values in e
ofstream out(filename.c_str());
out << e;
out.close();

Or if you want to use stream read and write then you just replace relevant code in operators implementation.

When the variables are private inside your struct/class then you need to declare operators as friend methods.

You implement any format/separators that you like. When your string include spaces use getline() that takes a string and stream instead of >> because operator>> uses spaces as delimiters by default. Depends on your separators.

Solution 2

It's called serialization. There are many serialization threads on SO.

There are also a nice serialization library included in boost.

http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/index.html

basically you can do

myFile<<myObject 

and

myFile>>myObject

with boost serialization.

Solution 3

If you have:

struct A {
    char a[30], b[25], c[15];
    int x;
}

then you can write it all just with write(fh, ptr, sizeof(struct a)).

Of course, this isn't portable (because we're not saving the endieness or size of "int," but that may not be an issue for you.

If you have:

struct A {
    char *a, *b, *c;
    int d;
}

then you're not looking to write the object; you're looking to serialize it. Your best bet is to look in the Boost libraries and use their serialization routines, because it's not an easy problem in languages without reflection.

Solution 4

There's not really a simple way, it's C++ after all, not PHP, or JavaScript.

http://www.parashift.com/c++-faq-lite/serialization.html

Boost also has some library for it: http://www.boost.org/doc/libs/release/libs/serialization ... like Tronic already mentioned :)

Solution 5

The better method is to write each field individually along with the string length.

As an alternative, you can create a char array (or std::vector<char>) and write all the members into the buffer, then write the buffer to the output.

The underlying thorn is that a compiler is allowed to insert padding between members in a class or structure. Use memcpy or std::copy will result in padding bytes written to the output.

Just remember that you need to either write the string lengths and the content or the content followed by some terminating character.

Other people will suggest checking out the Boost Serialization library.

Share:
42,737
neuromancer
Author by

neuromancer

Updated on November 19, 2020

Comments

  • neuromancer
    neuromancer over 3 years

    I have an object with several text strings as members. I want to write this object to the file all at once, instead of writing each string to file. How can I do that?