#include <cassert>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
//From http://richelbilderbeek.nl/CppVectorToStreamExample2.htm
std::ostream& operator<<(std::ostream& os, const std::vector<std::string>& w)
{
//Copy the original std::vector
std::vector<std::string> v = w;
//Preformat data
std::for_each(v.begin(),v.end(),
[&os](std::string& s)
{
//The only assertion done on the input
//Note that users nearly every use bell characters in their text inputs
assert(std::count(s.begin(),s.end(),'\b') == 0 && "Text must not contain a bell character");
std::replace(s.begin(),s.end(),' ','\b');
if (s == "</>") s = "<\b/>";
}
);
//Check data
#ifndef NDEBUG
std::for_each(v.begin(),v.end(),
[&os](const std::string& s)
{
assert(s != "</>" && "Text shoule not be '</>' anymore");
assert(std::count(s.begin(),s.end(),' ') == 0 && "Text should not contain spaces anymore");
}
);
#endif
//Write start tag
os << "<>\n";
//Write data
std::for_each(v.begin(),v.end(),
[&os](const std::string& s)
{
os << s << '\n';
}
);
//Write end tag
os << "</>";
return os;
}
//From http://richelbilderbeek.nl/CppVectorToStreamExample2.htm
std::istream& operator>>(std::istream& is, std::vector<std::string>& v)
{
//Read start tag
{
std::string s; is >> s; assert(s == std::string("<>"));
}
//Read data until end tag
while (1)
{
std::string s;
is >> s;
if (s == std::string("</>")) return is;
if (s == "<\b/>") s = "</>";
std::replace(s.begin(),s.end(),'\b',' ');
v.push_back(s);
}
}
///Names is a struct to contain a std::vector<std::string>
///Without it, boost::property_tree cannot parse People
///See commented code below for a Names-less version that will not compile
struct Names
{
std::vector<std::string> m_names;
};
struct People
{
void AddName(const std::string& name)
{
m_names.m_names.push_back(name);
}
const std::vector<std::string>& GetNames() const
{
return m_names.m_names;
}
void SetNames(const Names& names)
{
m_names = names;
}
void Load(const std::string &filename)
{
boost::property_tree::ptree t;
boost::property_tree::xml_parser::read_xml(filename,t);
m_names = t.get<Names>("People.names");
}
void Save(const std::string &filename) const
{
boost::property_tree::ptree t;
t.put("People.names", m_names);
boost::property_tree::xml_parser::write_xml(filename,t);
}
private:
Names m_names;
};
bool operator==(const People& lhs, const People& rhs)
{
return lhs.GetNames() == rhs.GetNames();
}
std::ostream& operator<<(std::ostream& os, const Names& p)
{
os << p.m_names;
return os;
}
std::istream& operator>>(std::istream& is, Names& p)
{
is >> p.m_names;
return is;
}
std::ostream& operator<<(std::ostream& os, const People& p)
{
os << p.GetNames();
return os;
}
std::istream& operator>>(std::istream& is, People& p)
{
Names names;
is >> names; p.SetNames(names);
return is;
}
int main()
{
//Test reading and writing of std::vector<std::string>
//From http://richelbilderbeek.nl/CppVectorToStreamExample2.htm
{
//Go ahead, create an entry that breaks the code!
const std::vector<std::string> v(
{
"aahs",
"aals",
"abac",
"abas",
"</>",
" </>",
" </> ",
"_</>",
"</>_",
"</></>",
"</> </>",
"</>_</>",
"abba",
"abbe",
"abbs",
"abed",
"abet",
"abid"
}
);
const std::string filename = "tmp.txt";
//Write to file
{
std::ofstream f(filename.c_str());
f << v;
}
//Read from file
{
std::vector<std::string> w;
std::ifstream f(filename.c_str());
f >> w;
if (v != w)
{
std::copy(w.begin(),w.end(),std::ostream_iterator<std::string>(std::cout,"\n"));
}
assert(v == w && "Because the algorithm is excellent, this will never happen B-)");
}
}
//Check writing/reading people to/from stream in plain text
//Note that this also works, without using boost::property_tree
const std::string filename = "tmp.txt";
{
People p;
p.AddName("Bilderbikkel");
p.AddName("Richel Bilderbeek");
{
std::ofstream f(filename.c_str());
f << p;
}
{
std::ifstream f(filename.c_str());
People q;
f >> q;
assert(p == q);
}
}
//Check writing/reading people to/from stream using XML
{
People p;
p.AddName("Bilderbikkel");
p.AddName("Richel Bilderbeek");
{
p.Save(filename);
}
{
People q;
q.Load(filename);
assert(p == q);
}
}
//Display tmp.txt
{
std::cout << "Displaying '" << filename << "':\n";
std::ifstream f(filename);
while(!f.eof())
{
std::string s;
std::getline(f,s);
std::cout << s << '\n';
}
}
}
/* Screen output:
Displaying 'tmp.txt':
<?xml version="1.0" encoding="utf-8"?>
<People><names><>
Bilderbikkel
RichelBilderbeek
</></names></People>
*/
/*
*
*
#include <cassert>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
//From http://richelbilderbeek.nl/CppVectorToStreamExample2.htm
std::ostream& operator<<(std::ostream& os, const std::vector<std::string>& w)
{
//Copy the original std::vector
std::vector<std::string> v = w;
//Preformat data
std::for_each(v.begin(),v.end(),
[&os](std::string& s)
{
//The only assertion done on the input
//Note that users nearly every use bell characters in their text inputs
assert(std::count(s.begin(),s.end(),'\b') == 0 && "Text must not contain a bell character");
std::replace(s.begin(),s.end(),' ','\b');
if (s == "</>") s = "<\b/>";
}
);
//Check data
#ifndef NDEBUG
std::for_each(v.begin(),v.end(),
[&os](const std::string& s)
{
assert(s != "</>" && "Text shoule not be '</>' anymore");
assert(std::count(s.begin(),s.end(),' ') == 0 && "Text should not contain spaces anymore");
}
);
#endif
//Write start tag
os << "<>\n";
//Write data
std::for_each(v.begin(),v.end(),
[&os](const std::string& s)
{
os << s << '\n';
}
);
//Write end tag
os << "</>";
return os;
}
//From http://richelbilderbeek.nl/CppVectorToStreamExample2.htm
std::istream& operator>>(std::istream& is, std::vector<std::string>& v)
{
//Read start tag
{
std::string s; is >> s; assert(s == std::string("<>"));
}
//Read data until end tag
while (1)
{
std::string s;
is >> s;
if (s == std::string("</>")) return is;
if (s == "<\b/>") s = "</>";
std::replace(s.begin(),s.end(),'\b',' ');
v.push_back(s);
}
}
struct People
{
void AddName(const std::string& name)
{
m_names.push_back(name);
}
const std::vector<std::string>& GetNames() const
{
return m_names;
}
void SetNames(const std::vector<std::string>& names)
{
m_names = names;
}
void Load(const std::string &filename)
{
boost::property_tree::ptree t;
boost::property_tree::xml_parser::read_xml(filename,t);
m_names = t.get<std::vector<std::string> >("People.names");
}
void Save(const std::string &filename) const
{
boost::property_tree::ptree t;
t.put("People.names", this->m_names);
boost::property_tree::xml_parser::write_xml(filename,t);
}
private:
std::vector<std::string> m_names;
};
bool operator==(const People& lhs, const People& rhs)
{
return lhs.GetNames() == rhs.GetNames();
}
std::ostream& operator<<(std::ostream& os, const People& p)
{
os << p.GetNames();
return os;
}
std::istream& operator>>(std::istream& is, People& p)
{
std::vector<std::string> names;
is >> names; p.SetNames(names);
return is;
}
int main()
{
//Test reading and writing of std::vector<std::string>
//From http://richelbilderbeek.nl/CppVectorToStreamExample2.htm
{
//Go ahead, create an entry that breaks the code!
const std::vector<std::string> v(
{
"aahs",
"aals",
"abac",
"abas",
"</>",
" </>",
" </> ",
"_</>",
"</>_",
"</></>",
"</> </>",
"</>_</>",
"abba",
"abbe",
"abbs",
"abed",
"abet",
"abid"
}
);
const std::string filename = "tmp.txt";
//Write to file
{
std::ofstream f(filename.c_str());
f << v;
}
//Read from file
{
std::vector<std::string> w;
std::ifstream f(filename.c_str());
f >> w;
if (v != w)
{
std::copy(w.begin(),w.end(),std::ostream_iterator<std::string>(std::cout,"\n"));
}
assert(v == w && "Because the algorithm is excellent, this will never happen B-)");
}
}
//Check writing/reading people to/from stream in plain text
//Note that this also works, without using boost::property_tree
const std::string filename = "tmp.txt";
{
People p;
p.AddName("Bilderbikkel");
p.AddName("Richel Bilderbeek");
{
std::ofstream f(filename.c_str());
f << p;
}
{
std::ifstream f(filename.c_str());
People q;
f >> q;
assert(p == q);
}
}
//Check writing/reading people to/from stream using XML
{
People p;
p.AddName("Bilderbikkel");
p.AddName("Richel Bilderbeek");
{
p.Save(filename);
}
{
People q;
q.Load(filename);
assert(p == q);
}
}
//Display tmp.txt
{
std::cout << "Displaying '" << filename << "':\n";
std::ifstream f(filename);
while(!f.eof())
{
std::string s;
std::getline(f,s);
std::cout << s << '\n';
}
}
}
*/
|