Master-Antonio
Master-Antonio

Reputation: 149

Read/Write binary file using struct in struct

I need to create a binary file and write the current state of the struct created.

This struct have a other struct. Something like this :

struct A {
    bool flag=true;
    int n;
};

struct B
{
    int n1;
    A *array;
};

How write all in the binary file?

But specially how read from the binary file and load all in the struct B again, and then load all in A *array.

Thanks a lot.

I tried this way, but sometime give me a exception and block all (violation of read access).

HOW WRITE :

ofstream save("binary.bin", ios::binary);
    if (!save) {
        cerr << "Error creation file ";
    }
    else {
        save.write(reinterpret_cast<char*>(&prova), sizeof(prova));
    }

    binary.close();

HOW READ and PRINT:

save.read(reinterpret_cast<char*>(&prova), sizeof(prova));
for (size_t i = 0; i != try.n1; ++i)
   {
   cout << "....." << try.n1 <<endl;
   cout << "..... "<< try.array[i].n <<" ";
   cout << ".....: "<<try.array[i].flag<< endl;
  }

Upvotes: 0

Views: 132

Answers (1)

R Sahu
R Sahu

Reputation: 206567

Writting a single instance of A in binary is simple since its a POD type:

std::ofstream outfile = {...};
A a = { ... };
outfile.write(reinterpret_cast<char const*>(&a), sizeof(a));

Writing a single instance of B, OTOH, is not as simple. You'll have to write n1 first and then the elements from the array.

B b = { ... };

// Write the number of elements first.
outfile.write(reinterpret_cast<char const*>(&b.n1), sizeof(b.n1));

// Now write the elements.
outfile.write(reinterpret_cast<char const*>(b.array), sizeof(A)*b.n1);

Reading from a binary file is, obviously, the inverse of that. Reading to an instance of A is simple.

std:ifstream infile = { ... };

A a;
infile.read(retinterpret_cast<char*>(&a), sizeof(a));

Reading to an instance of B is a little bit more involved. You'll have to read the size first, then allocate memory for the elements of the array, and then read the elements of the array.

B b;

// Read the number of elements
infile.read(retinterpret_cast<char*>(&b.n1), sizeof(b.n1));

// Allocate memory for the elements of the array.
b.array = new A[b.n1];

// Now read the elements of the array.
infile.read(retinterpret_cast<char*>(b.array), sizeof(A)*b.n1);

You can simplify some of that code by using helper functions that reduce the use of retinterpret_cast all over your code.

namespace MyApp
{
   template <typename T>
   std::ostream& write(std::ostream& out, T const& pod)
   {
      out.write(reinterpret_cast<char const*>(&pod), sizeof(T));
      return out;
   }

   template <typename T>
   std::ostream& write(std::ostream& out, T* array, int numElements)
   {
      out.write(reinterpret_cast<char const*>(array), sizeof(T)*numElements);
      return out;
   }

   template <typename T>
   std:istream read(std::istream& in, T& pod)
   {
      in.read(reinterpret_cast<char*>(&pod), sizeof(T));
      return in;
   }

   template <typename T>
   std:istream& read(std:istream& in, T* array, int numElements)
   {
      in.read(reinterpret_cast<char*>(array), sizeof(T)*numElements);
      return in;
   }
}

Now, you can use:

// Write a
MyApp::write(outfile, a);

// Read a
MyApp::read(infile, a);

// Write b
MyApp::write(outfile, b.n1);
MyApp::write(outfile, b.array, b.n1);

// Read b
MyApp::write(infile, b.n1);
b.array = new A[b.n1];
MyApp::write(infile, b.array, b.n1);

Upvotes: 1

Related Questions