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

老外写的一段代码,在Server中编写这个类读取配置文件比较实用 
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. * 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. }  



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[] = "  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. }  


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 

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


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


原文地址:https://www.cnblogs.com/java20130726/p/3218453.html