Reputation: 750
I have a piece of code to write elements of an array to a file (serialize) and then read it back (deserialize) Here it is :
#include<stdio.h>
void serialize(int *arr,int n,FILE *fp)
{
int i=0;
for( ; i<=n-1 ; i++)
fprintf(fp,"%d ",arr[i]); // The elements of array go into the file
}
void deserialize(FILE *fp)
{
int temp;
while(1)
{
if(fscanf(fp,"%d",&temp))
printf("%d ",temp); // The Contents of file tree.txt are written to console
else
break;
}
}
int main()
{
int arr[] = {20,8,-1,-1,22,-1,-1};
FILE *fp = fopen("tree.txt", "w");
if (fp == NULL)
{
puts("Could not open file");
return 0;
}
serialize(arr,n, fp);
fclose(fp);
fp = fopen("tree.txt", "r");
deserialize(fp);
fclose(fp);
return 0;
}
How to achieve this using the objects ofstream and ifstream in C++?
Upvotes: 0
Views: 712
Reputation: 3089
You can use other approach: ostream_iterator
and istream_iterator
#include <fstream>
#include <iostream>
#include <iterator>
#include <algorithm>
int main(int, char **)
{
int arr[] = {20,8,-1,-1,22,-1,-1};
// write to console
std::copy(arr, arr + 7, std::ostream_iterator<int>(std::cout, " "));
// write on file
std::cout << std::endl << "Writing on file" << std::endl;
std::ofstream myOfile("./out.dat");
if (myOfile.is_open())
{
std::ostream_iterator<int> out_iter(myOfile, " ");
std::copy(arr, arr + 7, out_iter);
myOfile.close();
}
// read from file
std::cout << std::endl << "Reading from file" << std::endl;
std::ifstream myIfile("./out.dat");
if (myIfile.is_open())
{
std::copy(std::istream_iterator<int>(myIfile),
std::istream_iterator<int>(),
std::ostream_iterator<int>(std::cout, " "));
myIfile.close();
}
return 0;
}
Upvotes: 2
Reputation: 22890
object streams operator overloading requires to provide an overload for a given type. Which means you need to wrap your custom array, for instance like
struct my_array
{
int *arr;
int n;
};
and then define the overloads
std::ostream& operator<<(std::ostream& os, const my_array& foo)
{
//same as serialize
int i=0;
for( ; i<=foo.n-1 ; i++)
os << foo.arr[i];
return os;
}
std::istream& operator>>(std::istream& is, my_array& dt)
{
//do something
return is;
}
There is an issue with your code. serialization and deserialization are not strictly inverse operations. This is due to the fact that when reading you have no clue on how many values you are supposed to read. Thus trying to serialize your data and then something else and read back will always fail.
fstream s;
my_array a;
bar b;
s << a << b;
...
my_array x;
bar y;
s >> x >> y; //endof, failbit set
Here not only y ! = b
, but x != a
. To add insult to the injury, the content of both x
and y
will be different depending on whether you are c++11 or not.
Upvotes: 3