• c++配置类


    网上一个热心的大牛分享了一个c++配置类,如下:
    Config.h 

    [cpp] view plaincopy
     
    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. }    


    Config.cpp

    [cpp] view plaincopy
     
    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. }    

    引自:http://cooker.iteye.com/blog/777455

    在其基础上做了下包装:

    Main_config.h

    [cpp] view plaincopy
     
    1. // Main_config.h: interface for the Main_config class.  
    2. //  
    3. //////////////////////////////////////////////////////////////////////  
    4.   
    5. #if !defined(AFX_MAIN_CONFIG_H__B4BEEE3F_3D81_4428_A25F_66E6B56318F2__INCLUDED_)  
    6. #define AFX_MAIN_CONFIG_H__B4BEEE3F_3D81_4428_A25F_66E6B56318F2__INCLUDED_  
    7.   
    8. #include "const.h"  
    9. #include "Config.h"  
    10.   
    11. // 主配置文件封装  
    12. class Main_config  
    13. {  
    14. public:  
    15.     // @brief 获取实例  
    16.     static Main_config& instance();  
    17.   
    18.     // @brief 获取配置Config对象  
    19.     const Config& get_config();  
    20.   
    21.     // @brief 导入配置文件  
    22.     bool load_config();  
    23.   
    24. private:  
    25.     Main_config();  
    26.   
    27.     virtual ~Main_config();  
    28.   
    29.     // 配置对象  
    30.     Config* _config;  
    31.   
    32.     // 配置文件路径  
    33.     char _conf_path[PATH_SIZE];  
    34.   
    35.     // 配置文件名  
    36.     char _conf_name[PATH_SIZE];  
    37. };  
    38.   
    39. #endif // !defined(AFX_MAIN_CONFIG_H__B4BEEE3F_3D81_4428_A25F_66E6B56318F2__INCLUDED_)  


    Main_config.cpp

    [cpp] view plaincopy
     
    1. // Main_config.cpp: implementation of the Main_config class.  
    2. //  
    3. //////////////////////////////////////////////////////////////////////  
    4.   
    5. #include "Main_config.h"  
    6. #include "const.h"  
    7.   
    8. //////////////////////////////////////////////////////////////////////  
    9. // Construction/Destruction  
    10. //////////////////////////////////////////////////////////////////////  
    11.   
    12. Main_config::Main_config()  
    13. {  
    14.     snprintf(_conf_path, sizeof(_conf_path), "%s""../conf");  
    15.     snprintf(_conf_name, sizeof(_conf_name), "%s/%s.%s", _conf_path, execname, "conf");  
    16. }  
    17.   
    18. Main_config::~Main_config()  
    19. {  
    20.     if(_config)  
    21.     {  
    22.         delete _config;  
    23.     }  
    24. }  
    25.   
    26. bool Main_config::load_config()  
    27. {  
    28.     bool ret = true;  
    29.       
    30.     _config = new(std::nothrow) Config(_conf_name);  
    31.     if (_config == NULL)  
    32.     {  
    33.         return false;  
    34.     }  
    35.   
    36.     return ret;  
    37. }  
    38.   
    39. Main_config& Main_config::instance()  
    40. {  
    41.     static Main_config main_config;  
    42.     return main_config;  
    43. }  
    44.   
    45. const Config& Main_config::get_config()  
    46. {  
    47.     return *_config;  
    48. }  


    使用:

    [cpp] view plaincopy
     
    1. #include "Main_config.h"  
    2. ....  
    3. // 加载主配置文件  
    4. if (!Main_config::instance().load_config())  
    5. {  
    6.     std::cout << "Main_config::load_config() failed" << std::endl;  
    7.     return false;  
    8. }  
    9. //从配置文件中读取端口号  
    10. _port = Main_config::instance().get_config().Read("PORT", 0);   
    11. ....  


    simple and reliable!

  • 相关阅读:
    Codeforces Round #408 (Div. 2) C
    Codeforces Round #408 (Div. 2) B
    Codeforces Round #408 (Div. 2) A
    我眼中的Linux设备树(五 根节点)
    我眼中的Linux设备树(四 中断)
    我眼中的Linux设备树(三 属性)
    我眼中的Linux设备树(二 节点)
    我眼中的Linux设备树(一 概述)
    为什么你应该(从现在开始就)写博客
    LCD正向扫描和反向扫描
  • 原文地址:https://www.cnblogs.com/chunlinge/p/3435522.html
Copyright © 2020-2023  润新知