[转载]config文件的一个很好的实现

以下是转载于网上的一个很好的config文件的实现,留存以备案

  1 //Config.h
  2 #pragma once
  3 
  4 #include <string>
  5 #include <map>
  6 #include <iostream>
  7 #include <fstream>
  8 #include <sstream>
  9 
 10 
 11 /*
 12 * rief Generic configuration Class
 13 *
 14 */
 15 class Config {
 16     // Data
 17 protected:
 18     std::string m_Delimiter;  //!< separator between key and value
 19     std::string m_Comment;    //!< separator between value and comments
 20     std::map<std::string,std::string> m_Contents;  //!< extracted keys and values
 21 
 22     typedef std::map<std::string,std::string>::iterator mapi;
 23     typedef std::map<std::string,std::string>::const_iterator mapci;
 24     // Methods
 25 public:
 26 
 27     Config( std::string filename,std::string delimiter = "=",std::string comment = "#" );
 28     Config();
 29     template<class T> T Read( const std::string& in_key ) const;  //!<Search for key and read value or optional default value, call as read<T>
 30     template<class T> T Read( const std::string& in_key, const T& in_value ) const;
 31     template<class T> bool ReadInto( T& out_var, const std::string& in_key ) const;
 32     template<class T>
 33     bool ReadInto( T& out_var, const std::string& in_key, const T& in_value ) const;
 34     bool FileExist(std::string filename);
 35     void ReadFile(std::string filename,std::string delimiter = "=",std::string comment = "#" );
 36 
 37     // Check whether key exists in configuration
 38     bool KeyExists( const std::string& in_key ) const;
 39 
 40     // Modify keys and values
 41     template<class T> void Add( const std::string& in_key, const T& in_value );
 42     void Remove( const std::string& in_key );
 43 
 44     // Check or change configuration syntax
 45     std::string GetDelimiter() const { return m_Delimiter; }
 46     std::string GetComment() const { return m_Comment; }
 47     std::string SetDelimiter( const std::string& in_s )
 48     { std::string old = m_Delimiter;  m_Delimiter = in_s;  return old; }  
 49     std::string SetComment( const std::string& in_s )
 50     { std::string old = m_Comment;  m_Comment =  in_s;  return old; }
 51 
 52     // Write or read configuration
 53     friend std::ostream& operator<<( std::ostream& os, const Config& cf );
 54     friend std::istream& operator>>( std::istream& is, Config& cf );
 55 
 56 protected:
 57     template<class T> static std::string T_as_string( const T& t );
 58     template<class T> static T string_as_T( const std::string& s );
 59     static void Trim( std::string& inout_s );
 60 
 61 
 62     // Exception types
 63 public:
 64     struct File_not_found {
 65         std::string filename;
 66         File_not_found( const std::string& filename_ = std::string() )
 67             : filename(filename_) {} };
 68         struct Key_not_found {  // thrown only by T read(key) variant of read()
 69             std::string key;
 70             Key_not_found( const std::string& key_ = std::string() )
 71                 : key(key_) {} };
 72 };
 73 
 74 
 75 /* static */
 76 template<class T>
 77 std::string Config::T_as_string( const T& t )
 78 {
 79     // Convert from a T to a string
 80     // Type T must support << operator
 81     std::ostringstream ost;
 82     ost << t;
 83     return ost.str();
 84 }
 85 
 86 
 87 /* static */
 88 template<class T>
 89 T Config::string_as_T( const std::string& s )
 90 {
 91     // Convert from a string to a T
 92     // Type T must support >> operator
 93     T t;
 94     std::istringstream ist(s);
 95     ist >> t;
 96     return t;
 97 }
 98 
 99 
100 /* static */
101 template<>
102 inline std::string Config::string_as_T<std::string>( const std::string& s )
103 {
104     // Convert from a string to a string
105     // In other words, do nothing
106     return s;
107 }
108 
109 
110 /* static */
111 template<>
112 inline bool Config::string_as_T<bool>( const std::string& s )
113 {
114     // Convert from a string to a bool
115     // Interpret "false", "F", "no", "n", "0" as false
116     // Interpret "true", "T", "yes", "y", "1", "-1", or anything else as true
117     bool b = true;
118     std::string sup = s;
119     for( std::string::iterator p = sup.begin(); p != sup.end(); ++p )
120         *p = toupper(*p);  // make string all caps
121     if( sup==std::string("FALSE") || sup==std::string("F") ||
122         sup==std::string("NO") || sup==std::string("N") ||
123         sup==std::string("0") || sup==std::string("NONE") )
124         b = false;
125     return b;
126 }
127 
128 
129 template<class T>
130 T Config::Read( const std::string& key ) const
131 {
132     // Read the value corresponding to key
133     mapci p = m_Contents.find(key);
134     if( p == m_Contents.end() ) throw Key_not_found(key);
135     return string_as_T<T>( p->second );
136 }
137 
138 
139 template<class T>
140 T Config::Read( const std::string& key, const T& value ) const
141 {
142     // Return the value corresponding to key or given default value
143     // if key is not found
144     mapci p = m_Contents.find(key);
145     if( p == m_Contents.end() ) return value;
146     return string_as_T<T>( p->second );
147 }
148 
149 
150 template<class T>
151 bool Config::ReadInto( T& var, const std::string& key ) const
152 {
153     // Get the value corresponding to key and store in var
154     // Return true if key is found
155     // Otherwise leave var untouched
156     mapci p = m_Contents.find(key);
157     bool found = ( p != m_Contents.end() );
158     if( found ) var = string_as_T<T>( p->second );
159     return found;
160 }
161 
162 
163 template<class T>
164 bool Config::ReadInto( T& var, const std::string& key, const T& value ) const
165 {
166     // Get the value corresponding to key and store in var
167     // Return true if key is found
168     // Otherwise set var to given default
169     mapci p = m_Contents.find(key);
170     bool found = ( p != m_Contents.end() );
171     if( found )
172         var = string_as_T<T>( p->second );
173     else
174         var = value;
175     return found;
176 }
177 
178 
179 template<class T>
180 void Config::Add( const std::string& in_key, const T& value )
181 {
182     // Add a key with given value
183     std::string v = T_as_string( value );
184     std::string key=in_key;
185     trim(key);
186     trim(v);
187     m_Contents[key] = v;
188     return;
189 }
  1 // Config.cpp
  2 
  3 #include "Config.h"
  4 
  5 using namespace std;
  6 
  7 
  8 Config::Config( string filename, string delimiter,
  9                string comment )
 10                : m_Delimiter(delimiter), m_Comment(comment)
 11 {
 12     // Construct a Config, getting keys and values from given file
 13 
 14     std::ifstream in( filename.c_str() );
 15 
 16     if( !in ) throw File_not_found( filename ); 
 17 
 18     in >> (*this);
 19 }
 20 
 21 
 22 Config::Config()
 23 : m_Delimiter( string(1,'=') ), m_Comment( string(1,'#') )
 24 {
 25     // Construct a Config without a file; empty
 26 }
 27 
 28 
 29 
 30 bool Config::KeyExists( const string& key ) const
 31 {
 32     // Indicate whether key is found
 33     mapci p = m_Contents.find( key );
 34     return ( p != m_Contents.end() );
 35 }
 36 
 37 
 38 /* static */
 39 void Config::Trim( string& inout_s )
 40 {
 41     // Remove leading and trailing whitespace
 42     static const char whitespace[] = " 
	v
f";
 43     inout_s.erase( 0, inout_s.find_first_not_of(whitespace) );
 44     inout_s.erase( inout_s.find_last_not_of(whitespace) + 1U );
 45 }
 46 
 47 
 48 std::ostream& operator<<( std::ostream& os, const Config& cf )
 49 {
 50     // Save a Config to os
 51     for( Config::mapci p = cf.m_Contents.begin();
 52         p != cf.m_Contents.end();
 53         ++p )
 54     {
 55         os << p->first << " " << cf.m_Delimiter << " ";
 56         os << p->second << std::endl;
 57     }
 58     return os;
 59 }
 60 
 61 void Config::Remove( const string& key )
 62 {
 63     // Remove key and its value
 64     m_Contents.erase( m_Contents.find( key ) );
 65     return;
 66 }
 67 
 68 std::istream& operator>>( std::istream& is, Config& cf )
 69 {
 70     // Load a Config from is
 71     // Read in keys and values, keeping internal whitespace
 72     typedef string::size_type pos;
 73     const string& delim  = cf.m_Delimiter;  // separator
 74     const string& comm   = cf.m_Comment;    // comment
 75     const pos skip = delim.length();        // length of separator
 76 
 77     string nextline = "";  // might need to read ahead to see where value ends
 78 
 79     while( is || nextline.length() > 0 )
 80     {
 81         // Read an entire line at a time
 82         string line;
 83         if( nextline.length() > 0 )
 84         {
 85             line = nextline;  // we read ahead; use it now
 86             nextline = "";
 87         }
 88         else
 89         {
 90             std::getline( is, line );
 91         }
 92 
 93         // Ignore comments
 94         line = line.substr( 0, line.find(comm) );
 95 
 96         // Parse the line if it contains a delimiter
 97         pos delimPos = line.find( delim );
 98         if( delimPos < string::npos )
 99         {
100             // Extract the key
101             string key = line.substr( 0, delimPos );
102             line.replace( 0, delimPos+skip, "" );
103 
104             // See if value continues on the next line
105             // Stop at blank line, next line with a key, end of stream,
106             // or end of file sentry
107             bool terminate = false;
108             while( !terminate && is )
109             {
110                 std::getline( is, nextline );
111                 terminate = true;
112 
113                 string nlcopy = nextline;
114                 Config::Trim(nlcopy);
115                 if( nlcopy == "" ) continue;
116 
117                 nextline = nextline.substr( 0, nextline.find(comm) );
118                 if( nextline.find(delim) != string::npos )
119                     continue;
120 
121                 nlcopy = nextline;
122                 Config::Trim(nlcopy);
123                 if( nlcopy != "" ) line += "
";
124                 line += nextline;
125                 terminate = false;
126             }
127 
128             // Store key and value
129             Config::Trim(key);
130             Config::Trim(line);
131             cf.m_Contents[key] = line;  // overwrites if key is repeated
132         }
133     }
134 
135     return is;
136 }
137 bool Config::FileExist(std::string filename)
138 {
139     bool exist= false;
140     std::ifstream in( filename.c_str() );
141     if( in ) 
142         exist = true;
143     return exist;
144 }
145 
146 void Config::ReadFile( string filename, string delimiter,
147                       string comment )
148 {
149     m_Delimiter = delimiter;
150     m_Comment = comment;
151     std::ifstream in( filename.c_str() );
152 
153     if( !in ) throw File_not_found( filename ); 
154 
155     in >> (*this);
156 }
 1 //main.cpp
 2 #include "Config.h"
 3 int main()
 4 {
 5     int port;
 6     std::string ipAddress;
 7     std::string username;
 8     std::string password;
 9     const char ConfigFile[]= "config.txt"; 
10     Config configSettings(ConfigFile);
11     
12     port = configSettings.Read("port", 0);
13     ipAddress = configSettings.Read("ipAddress", ipAddress);
14     username = configSettings.Read("username", username);
15     password = configSettings.Read("password", password);
16     std::cout<<"port:"<<port<<std::endl;
17     std::cout<<"ipAddress:"<<ipAddress<<std::endl;
18     std::cout<<"username:"<<username<<std::endl;
19     std::cout<<"password:"<<password<<std::endl;
20     
21     return 0;
22 }

config.txt的文件内容: 
ipAddress=10.10.90.125 
port=3001 
username=mark 
password=2d2df5a 


编译运行输出: 
port:3001 
ipAddress:10.10.90.125 
username:mark 
password:2d2df5a 

原文地址:http://cooker.iteye.com/blog/777455

原文地址:https://www.cnblogs.com/jiayouwyhit/p/3836510.html