首页 > 代码库 > [转]C++编写Config类读取配置文件

[转]C++编写Config类读取配置文件

C++代码  收藏代码
  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. * \brief Generic configuration Class 
  13. */  
  14. class Config {  
  15.     // Data  
  16. protected:  
  17.     std::string m_Delimiter;  //!< separator between key and value  
  18.     std::string m_Comment;    //!< separator between value and comments  
  19.     std::map<std::string,std::string> m_Contents;  //!< extracted keys and values  
  20.   
  21.     typedef std::map<std::string,std::string>::iterator mapi;  
  22.     typedef std::map<std::string,std::string>::const_iterator mapci;  
  23.     // Methods  
  24. public:  
  25.   
  26.     Config( std::string filename,std::string delimiter = "=",std::string comment = "#" );  
  27.     Config();  
  28.     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>  
  29.     template<class T> T Read( const std::string& in_key, const T& in_value ) const;  
  30.     template<class T> bool ReadInto( T& out_var, const std::string& in_key ) const;  
  31.     template<class T>  
  32.     bool ReadInto( T& out_var, const std::string& in_key, const T& in_value ) const;  
  33.     bool FileExist(std::string filename);  
  34.     void ReadFile(std::string filename,std::string delimiter = "=",std::string comment = "#" );  
  35.   
  36.     // Check whether key exists in configuration  
  37.     bool KeyExists( const std::string& in_key ) const;  
  38.   
  39.     // Modify keys and values  
  40.     template<class T> void Add( const std::string& in_key, const T& in_value );  
  41.     void Remove( const std::string& in_key );  
  42.   
  43.     // Check or change configuration syntax  
  44.     std::string GetDelimiter() const { return m_Delimiter; }  
  45.     std::string GetComment() const { return m_Comment; }  
  46.     std::string SetDelimiter( const std::string& in_s )  
  47.     { std::string old = m_Delimiter;  m_Delimiter = in_s;  return old; }    
  48.     std::string SetComment( const std::string& in_s )  
  49.     { std::string old = m_Comment;  m_Comment =  in_s;  return old; }  
  50.   
  51.     // Write or read configuration  
  52.     friend std::ostream& operator<<( std::ostream& os, const Config& cf );  
  53.     friend std::istream& operator>>( std::istream& is, Config& cf );  
  54.   
  55. protected:  
  56.     template<class T> static std::string T_as_string( const T& t );  
  57.     template<class T> static T string_as_T( const std::string& s );  
  58.     static void Trim( std::string& inout_s );  
  59.   
  60.   
  61.     // Exception types  
  62. public:  
  63.     struct File_not_found {  
  64.         std::string filename;  
  65.         File_not_found( const std::string& filename_ = std::string() )  
  66.             : filename(filename_) {} };  
  67.         struct Key_not_found {  // thrown only by T read(key) variant of read()  
  68.             std::string key;  
  69.             Key_not_found( const std::string& key_ = std::string() )  
  70.                 : key(key_) {} };  
  71. };  
  72.   
  73.   
  74. /* static */  
  75. template<class T>  
  76. std::string Config::T_as_string( const T& t )  
  77. {  
  78.     // Convert from a T to a string  
  79.     // Type T must support << operator  
  80.     std::ostringstream ost;  
  81.     ost << t;  
  82.     return ost.str();  
  83. }  
  84.   
  85.   
  86. /* static */  
  87. template<class T>  
  88. T Config::string_as_T( const std::string& s )  
  89. {  
  90.     // Convert from a string to a T  
  91.     // Type T must support >> operator  
  92.     T t;  
  93.     std::istringstream ist(s);  
  94.     ist >> t;  
  95.     return t;  
  96. }  
  97.   
  98.   
  99. /* static */  
  100. template<>  
  101. inline std::string Config::string_as_T<std::string>( const std::string& s )  
  102. {  
  103.     // Convert from a string to a string  
  104.     // In other words, do nothing  
  105.     return s;  
  106. }  
  107.   
  108.   
  109. /* static */  
  110. template<>  
  111. inline bool Config::string_as_T<bool>( const std::string& s )  
  112. {  
  113.     // Convert from a string to a bool  
  114.     // Interpret "false", "F", "no", "n", "0" as false  
  115.     // Interpret "true", "T", "yes", "y", "1", "-1", or anything else as true  
  116.     bool b = true;  
  117.     std::string sup = s;  
  118.     for( std::string::iterator p = sup.begin(); p != sup.end(); ++p )  
  119.         *p = toupper(*p);  // make string all caps  
  120.     if( sup==std::string("FALSE") || sup==std::string("F") ||  
  121.         sup==std::string("NO") || sup==std::string("N") ||  
  122.         sup==std::string("0") || sup==std::string("NONE") )  
  123.         b = false;  
  124.     return b;  
  125. }  
  126.   
  127.   
  128. template<class T>  
  129. T Config::Read( const std::string& key ) const  
  130. {  
  131.     // Read the value corresponding to key  
  132.     mapci p = m_Contents.find(key);  
  133.     if( p == m_Contents.end() ) throw Key_not_found(key);  
  134.     return string_as_T<T>( p->second );  
  135. }  
  136.   
  137.   
  138. template<class T>  
  139. T Config::Read( const std::string& key, const T& value ) const  
  140. {  
  141.     // Return the value corresponding to key or given default value  
  142.     // if key is not found  
  143.     mapci p = m_Contents.find(key);  
  144.     if( p == m_Contents.end() ) return value;  
  145.     return string_as_T<T>( p->second );  
  146. }  
  147.   
  148.   
  149. template<class T>  
  150. bool Config::ReadInto( T& var, const std::string& key ) const  
  151. {  
  152.     // Get the value corresponding to key and store in var  
  153.     // Return true if key is found  
  154.     // Otherwise leave var untouched  
  155.     mapci p = m_Contents.find(key);  
  156.     bool found = ( p != m_Contents.end() );  
  157.     if( found ) var = string_as_T<T>( p->second );  
  158.     return found;  
  159. }  
  160.   
  161.   
  162. template<class T>  
  163. bool Config::ReadInto( T& var, const std::string& key, const T& value ) const  
  164. {  
  165.     // Get the value corresponding to key and store in var  
  166.     // Return true if key is found  
  167.     // Otherwise set var to given default  
  168.     mapci p = m_Contents.find(key);  
  169.     bool found = ( p != m_Contents.end() );  
  170.     if( found )  
  171.         var = string_as_T<T>( p->second );  
  172.     else  
  173.         var = value;  
  174.     return found;  
  175. }  
  176.   
  177.   
  178. template<class T>  
  179. void Config::Add( const std::string& in_key, const T& value )  
  180. {  
  181.     // Add a key with given value  
  182.     std::string v = T_as_string( value );  
  183.     std::string key=in_key;  
  184.     trim(key);  
  185.     trim(v);  
  186.     m_Contents[key] = v;  
  187.     return;  
  188. }  



C++代码  收藏代码
  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[] = " \n\t\v\r\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 += "\n";  
  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. }  


C++代码  收藏代码
  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 

这个类还有很多其他的方法,可以调用试试。

 

 

[转]C++编写Config类读取配置文件