-
February 11th, 2009, 07:34 AM
#1
Writing structures of vectors / std::string into binary file
Hi,
I am using the following structures
struct KeyValPair
{
std::string Key;
std::string Value
};
struct Properties
{
std::string PropertyName;
vector <KeyValPair > PropVal;
};
struct MainComponent
{
std::string MainName;
vector < Properties > Properties;
};
Now in my mail program, I have defined
vector < MainComponent > objComponent;
and I am storing say 10 components values inside this one.
I want these values of the 10 components the next time I execute the program. So the only option I have is to write to file as binary data right ??
Can someone show me how this can be achieved ?
I tried the FILE *fp; thingy and the fwrite and fread
E.g.
FILE*fp;
fp = fopen("c:\\Component.dat","wb");
fwrite(&objComponent,sizeof(objComponent),2,fp);
But i am getting errors. I dont know how to fill parameters for the fwrite since it contains vectors which can be variable.
I am forced to use only standard C++ libraries as this is part of a helper class for a bigger program.
Please do help me.... I am also googling since morning but without much success..
thanks in anticipation.
Also i would be delighted if someone would post with code examples to my program.
-
February 11th, 2009, 07:45 AM
#2
Re: Writing structures of vectors / std::string into binary file
You don't have to use FILE and probably shouldn't, as it's not really the "C++ way".You can use ofstream to write data to a file, and ifstream to read from a file.
Code:
std::ofstream stream;
stream.open("test.txt");
if(stream.fail())
throw std::runtime_error("Couldn't open test.txt.");
stream << "blah";
stream.close();
-
February 11th, 2009, 08:57 AM
#3
Re: Writing structures of vectors / std::string into binary file
When you have non-POD data (example std::string), there is
no easy way to read/write unformatted (binary). Basically, you
need to do it individually for each data member. I have
a few routines to aid in doing this. I can't post the actual codes,
but I can post some slightly simplified versions (which I have
not tested, but will give you an idea).
A) First, to read/write binary std::strings:
Code:
bool WriteUnformatted_string(std::ostream & out , const std::string & s)
{
std::string::size_type n = s.size();
out.write( reinterpret_cast<const char*>(&n) , sizeof(n) );
if (n > 0)
{
out.write( s.c_str() , n );
}
return !out.bad();
}
bool ReadUnformatted_string(std::istream & in , std::string & s)
{
// Note : With the upcoming changes to the C++ standard,
// you will not need the intermediate vector, since
// a std::string will be gaurenteed to have
// contigous storage (at least, I saw that posted)
std::string::size_type n;
in.read( reinterpret_cast<char*>(&n) , sizeof(n) );
if (n > 0)
{
std::vector<char> v(n);
in.read( &v[0] , n );
s.assign(&v[0],&v[0]+n);
}
else
{
s = "";
}
return !in.bad();
}
B) Next, to read/write unformatted non-POD vectors
Code:
template <typename T>
bool WriteUnformatted_vector_nonPOD(std::ostream & out , const std::vector<T> & v)
{
size_t n = v.size();
out.write( reinterpret_cast<char*>(&n) , sizeof(n) );
for (int i =0; i<n; ++i)
{
v[i].WriteUnformatted(out); // assumes a WriteUnformatted() member function
}
return !out.bad();
}
template <typename T>
bool ReadUnformatted_vector_nonPOD(std::istream & in , std::vector<T> & v)
{
v.clear();
size_t n;
in.read( reinterpret_cast<char*>(&n) , sizeof(n) );
if (n > 0)
{
T key_value;
v.reserve(n);
for (int i =0; i<n; ++i)
{
key_value.ReadUnformatted(in); // assumes a ReadUnformatted() member function
v.push_back(key_value);
}
}
return !in.bad();
}
C) Next modifying your classes
Code:
struct KeyValPair
{
std::string Key;
std::string Value;
bool WriteUnformatted(std::ostream & out) const
{
WriteUnformatted_string(out,Key);
WriteUnformatted_string(out,Value);
return !out.bad();
}
bool ReadUnformatted(std::istream & in)
{
ReadUnformatted_string(in,Key);
ReadUnformatted_string(in,Value);
return !in.bad();
}
};
struct Properties
{
std::string PropertyName;
std::vector <KeyValPair> PropVal;
bool WriteUnformatted(std::ostream & out) const
{
WriteUnformatted_string(out,PropertyName);
WriteUnformatted_vector_nonPOD(out,PropVal);
return !out.bad();
}
bool ReadUnformatted(std::istream & in)
{
ReadUnformatted_string(in,PropertyName);
ReadUnformatted_vector_nonPOD(in,PropVal);
return !in.bad();
}
};
struct MainComponent
{
std::string MainName;
std::vector < Properties > Properties;
bool WriteUnformatted(std::ostream & out) const
{
WriteUnformatted_string(out,MainName);
WriteUnformatted_vector_nonPOD(out,Properties);
return !out.bad();
}
bool ReadUnformatted(std::istream & in)
{
ReadUnformatted_string(in,MainName);
ReadUnformatted_vector_nonPOD(in,Properties);
return !in.bad();
}
};
D) Note: you should open files using ios::binary mode
E) None of this has been tested, but it should give you an
idea of what needs to be done.
Last edited by Philip Nicoletti; February 11th, 2009 at 09:37 AM.
-
February 11th, 2009, 10:35 AM
#4
Re: Writing structures of vectors / std::string into binary file
I don't think the OP meant that the objects have to be written as binary data, rather that they were unsure if it was the only way to do it.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|