Skip to content

Latest commit

 

History

History
138 lines (78 loc) · 14.1 KB

CppCompositeDataTypeToStreamExample1.md

File metadata and controls

138 lines (78 loc) · 14.1 KB

 

 

 

 

 

 

This write and read a composite data type to/from a std::stream example demonstrates a near-foolproof way. The program its setup is fine: a composite data type is created, written to file, a new composite data type is read from that same file and the program tests if the two are identical.

 

The assumptions for this approach to work are:

  • Text may not contain a bell ('\b') character

 

Note that the program will issue a failed assert when the assumption is violated. Wonder, how often have you given a bell character as input?

 

 

 

 

 

 

 

Technical facts

 

Application type(s)

Operating system(s) or programming environment(s)

IDE(s):

Project type:

C++ standard:

Compiler(s):

Libraries used:

  • STL STL: GNU ISO C++ Library, version 4.7.2

 

 

 

 

 

Qt project file: CppCompositeDataTypeToStreamExample1.pro

 


QT       -= core gui QMAKE_CXXFLAGS += -std=c++11 -Werror -Wextra TARGET = CppCompositeDataTypeToStreamExample1 CONFIG   += console SOURCES += main.cpp

 

 

 

 

 

main.cpp

 


#include <iostream> #include <iterator> #include <cassert> #include <algorithm> #include <fstream> #include <string> #include <vector> ///Write a std::vector<std::string> to std::ostream //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; } ///Read a std::vector<std::string> from std::ostream //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);   } } ///The composite data type that will be written/read to/from stream struct Data {   Data(     const std::string& s = "",     const std::vector<std::string>& v = {},     const std::vector<std::string>& w = {} )     : m_s(s), m_v(v), m_w(w) {}   std::string m_s;   std::vector<std::string> m_v;   std::vector<std::string> m_w; }; bool operator==(const Data& lhs, const Data& rhs) {   return lhs.m_s == rhs.m_s && lhs.m_v == rhs.m_v && lhs.m_w == rhs.m_w; } bool operator!=(const Data& lhs, const Data& rhs) {   return !(lhs == rhs); } std::ostream& operator<<(std::ostream& os, const Data& d) {   //Write s   {     std::string s = d.m_s;     std::replace(s.begin(),s.end(),' ','\b');     os << s << '\n';   }   os << d.m_v << '\n' << d.m_w;   return os; } std::istream& operator>>(std::istream& is, Data& d) {   //Read s   {     std::string s;     is >> s;     std::replace(s.begin(),s.end(),'\b',' ');     d.m_s = s;   }   is >> d.m_v >> d.m_w;   return is; } int main() {   //Go ahead, create an entry that breaks the code!   const Data data(     "<> </>",     {       "aahs",       "aals",       "abac",       "abas",       "</>",       " </>",       " </> ",       "_</>",       "</>_",       "</></>",       "</> </>",       "</>_</>",       "abba",       "abbe",       "abbs",       "abed",       "abet",       "abid"     }     ,     {       "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 << data;   }   //Read from file   {     Data other_data;     std::ifstream f(filename.c_str());     f >> other_data;     assert(data == other_data && "Because the algorithm is excellent, this will never happen B-)");   } }