zoukankan      html  css  js  c++  java
  • [转载]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

  • 相关阅读:
    CSS经典实用技巧10招
    分析与设计数据库模型的简单过程
    MS SQL数据类型及长度限制
    firefox与IE的nextSibling
    DIV+CSS布局总结
    Sql Server查找临时表,并删除
    powerDesigner15.1破解
    分别使用函数及游标实现SQL多行转一列
    生命的帐单
    北京有380万“北漂族” 没有归属感但不离不弃!
  • 原文地址:https://www.cnblogs.com/jiayouwyhit/p/3836510.html
Copyright © 2011-2022 走看看