Shilaly
Shilaly

Reputation: 23

Ways to write a vector of a class to a file

I'm not sure how I should word this, so I'll attempt to put it in code. (This has many errors I know it will not compile it is simply to show what I want to do because I can't put it in words)

    using namespace std; //for correctness sake
    class foo {
    public:
        foo(int a=0, int n=0);
        void stuff(int a);
        void function(int n);
        const int get_function() {return n;}
        const int get_stuff(){return a;}
    private: 
       int n, a;
    };
    struct Store{
        public: get_foo(){return vector<f.foo>;} //I'm not too sure of the syntax here but you get the idea
    private: 
        foo f;

    }

Basically I want to take all the information that is returned in class foo, and output this, formatted, to a file. Thing is, I need to make many of these within the file and it has to be able to read it back for it to be worth anything. So just appending each consecutive foo class to the file won't work(at least I don't see how).

I tried using ostream to overload the << operator, but I'm not sure how to call it to write it to the file. Any suggestions are welcome! Thanks.

Upvotes: 0

Views: 400

Answers (3)

6502
6502

Reputation: 114579

There are many tings wrong with your code.

So many that it's clear that you never read any C++ book and are just experimenting with a compiler.

Don't do that. C++ is really the worst language in the world to approach that way for many independent reasons.

No matter how smart you are.

Actually being smart is sort of a problem in certain areas because many C++ rules are not the result of a coherent logical design, but of historical evolution and committee decisions. Not even Hari Seldon would be able to foresee correctly what a committee would decide, you cannot deduce history.

Just pick a good book and read it cover to cover. There is no other sensible way to learn C++.

About writing structs to a file the topic is normally called "serialization" and takes care of the slightly more general problem of converting live objects into a dead sequence of bytes (written to a file or sent over the network) and the inverse problem "deserialization" of converting the sequence of bytes back into live objects (on the same system, on another identical system or even on a different system).

There are many facets of this problem, for example if your concern is about portability between systems, speed, size of the byte sequence, ability to reload bytes sequences that were saved back when your classes were slightly different because you evolved the program (versioning).

The simplest thing you can do is just fwrite things to a file, but this is most often simply nonsense in C++ and is a terrible way for many reasons even when it's technically possible. For example you cannot directly fwrite an std::vector object and hope to read it back.

Upvotes: 1

masoud
masoud

Reputation: 56549

I think your Store should be like this:

struct Store
{
public:
    std::vector<foo> get_foo()
    {
       return f;
    }

private: 
    std::vector<foo> f;
};

To overload << of std::ostream:

std::ostream& operator<<(std::ostream& out, const Store& f)
{
  for (auto &x : f.get_foo())
    out << x.get_function() << ", " << x.get_stuff() << "\n";

  return out;
}

//Without auto

std::ostream& operator<<(std::ostream& out, const Store& f)
{
  std::vector<foo> q = f;
  for (int i=0; i<q.size(); i++)
    out << q[i].get_function() << ", " << q[i].get_stuff() << "\n";

  return out;
}

Upvotes: 2

Ilya
Ilya

Reputation: 4689

I think you need something like this:

template<typename T>
std::ostream& operator << (std::ostream& out, const std::vector<T*>& elements)
{
  for (size_t i = 0; i < elements.size(); i++)
    out << elements[i] << ", ";
  return out << std::endl;
}

Upvotes: 0

Related Questions