Reading a key-value pair file in std :: map

I have a Visual Studio 2008 C ++ 03 project where I would like to read a key-value pair file in std :: map. For this, I created istreambuf_pair_iterator , as shown below:

 typedef std::map< std::string, std::string > Properties; class istreambuf_pair_iterator : public boost::iterator_adaptor< istreambuf_pair_iterator, std::pair< std::string, std::string >*, boost::use_default, boost::forward_traversal_tag > { public: istreambuf_pair_iterator() : sb_( 0 ) { }; explicit istreambuf_pair_iterator( std::istream& is ) : sb_( is.rdbuf() ) { }; private: void increment() { std::string line; std::istream is( sb_ ); std::getline( is, line ); // TODO: parse the key=value to a std::pair // where do I store the pair??? }; friend class boost::iterator_core_access; std::streambuf* sb_; }; Properties ReadProperties( const char* file ) { std::ifstream f( file ); Properties p; std::copy( istreambuf_pair_iterator( f ), istreambuf_pair_iterator(), std::inserter( p, p.end() ) ); return p; } 

As soon as I have std::pair<> made from a line read from the file where I store it so that it can be inserted std std::inserter in in std::map ?

+4
source share
1 answer

Why use boost for tasks that can be achieved with C ++ std? Just use istream_iterator with insert_iterator. To do this, you must define in the operators << and '→' in the std namespace for your pair<string,string> . Something like that:

 namespace std { // I am not happy that I had to put these stream operators in std namespace. // I had to because otherwise std iterators cannot find them // - you know this annoying C++ lookup rules... // I know one solution is to create new type inter-operable with this pair... // Just to lazy to do this - anyone knows workaround? istream& operator >> (istream& is, pair<string, string>& ps) { return is >> ps.first >> ps.second; } ostream& operator << (ostream& os, const pair<const string, string>& ps) { return os << ps.first << "==>>" << ps.second; } } 

And use:

std insert iterator:

  std::map<std::string, std::string> mps; std::insert_iterator< std::map<std::string, std::string> > mpsi(mps, mps.begin()); 

std istream iterator:

  const std::istream_iterator<std::pair<std::string,std::string> > eos; std::istream_iterator<std::pair<std::string,std::string> > its (is); 

Reading:

  std::copy(its, eos, mpsi); 

Writing (bonus):

  std::copy(mps.begin(), mps.end(), std::ostream_iterator<std::pair<std::string,std::string> >(std::cout, "\n")); 

Working example in ideone

+13
source

Source: https://habr.com/ru/post/1436886/


All Articles