Reputation: 149
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
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