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

  • Post author:
  • Post category:其他



老外写的一段代码,在Server中编写这个类读取配置文件比较实用


C++代码

收藏代码



  1. //Config.h



  2. #pragma once




  3. #include <string>



  4. #include <map>



  5. #include <iostream>



  6. #include <fstream>



  7. #include <sstream>





  8. /*



  9. * \brief Generic configuration Class



  10. *



  11. */



  12. class

    Config {


  13. // Data



  14. protected

    :

  15. std::string m_Delimiter;

    //!< separator between key and value


  16. std::string m_Comment;

    //!< separator between value and comments


  17. std::map<std::string,std::string> m_Contents;

    //!< extracted keys and values




  18. typedef

    std::map<std::string,std::string>::iterator mapi;


  19. typedef

    std::map<std::string,std::string>::const_iterator mapci;


  20. // Methods



  21. public

    :


  22. Config( std::string filename,std::string delimiter =

    “=”

    ,std::string comment =

    “#”

    );

  23. Config();


  24. 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>



  25. template

    <

    class

    T> T Read(

    const

    std::string& in_key,

    const

    T& in_value )

    const

    ;


  26. template

    <

    class

    T>

    bool

    ReadInto( T& out_var,

    const

    std::string& in_key )

    const

    ;


  27. template

    <

    class

    T>


  28. bool

    ReadInto( T& out_var,

    const

    std::string& in_key,

    const

    T& in_value )

    const

    ;


  29. bool

    FileExist(std::string filename);


  30. void

    ReadFile(std::string filename,std::string delimiter =

    “=”

    ,std::string comment =

    “#”

    );



  31. // Check whether key exists in configuration



  32. bool

    KeyExists(

    const

    std::string& in_key )

    const

    ;



  33. // Modify keys and values



  34. template

    <

    class

    T>

    void

    Add(

    const

    std::string& in_key,

    const

    T& in_value );


  35. void

    Remove(

    const

    std::string& in_key );



  36. // Check or change configuration syntax


  37. std::string GetDelimiter()

    const

    {

    return

    m_Delimiter; }

  38. std::string GetComment()

    const

    {

    return

    m_Comment; }

  39. std::string SetDelimiter(

    const

    std::string& in_s )

  40. { std::string old = m_Delimiter;  m_Delimiter = in_s;

    return

    old; }

  41. std::string SetComment(

    const

    std::string& in_s )

  42. { std::string old = m_Comment;  m_Comment =  in_s;

    return

    old; }



  43. // Write or read configuration



  44. friend

    std::ostream& operator<<( std::ostream& os,

    const

    Config& cf );


  45. friend

    std::istream& operator>>( std::istream& is, Config& cf );



  46. protected

    :


  47. template

    <

    class

    T>

    static

    std::string T_as_string(

    const

    T& t );


  48. template

    <

    class

    T>

    static

    T string_as_T(

    const

    std::string& s );


  49. static


    void

    Trim( std::string& inout_s );




  50. // Exception types



  51. public

    :


  52. struct

    File_not_found {

  53. std::string filename;

  54. File_not_found(

    const

    std::string& filename_ = std::string() )

  55. : filename(filename_) {} };


  56. struct

    Key_not_found {

    // thrown only by T read(key) variant of read()


  57. std::string key;

  58. Key_not_found(

    const

    std::string& key_ = std::string() )

  59. : key(key_) {} };

  60. };




  61. /* static */



  62. template

    <

    class

    T>

  63. std::string Config::T_as_string(

    const

    T& t )

  64. {


  65. // Convert from a T to a string



  66. // Type T must support << operator


  67. std::ostringstream ost;

  68. ost << t;


  69. return

    ost.str();

  70. }




  71. /* static */



  72. template

    <

    class

    T>

  73. T Config::string_as_T(

    const

    std::string& s )

  74. {


  75. // Convert from a string to a T



  76. // Type T must support >> operator


  77. T t;

  78. std::istringstream ist(s);

  79. ist >> t;


  80. return

    t;

  81. }




  82. /* static */



  83. template

    <>


  84. inline

    std::string Config::string_as_T<std::string>(

    const

    std::string& s )

  85. {


  86. // Convert from a string to a string



  87. // In other words, do nothing



  88. return

    s;

  89. }




  90. /* static */



  91. template

    <>


  92. inline


    bool

    Config::string_as_T<

    bool

    >(

    const

    std::string& s )

  93. {


  94. // Convert from a string to a bool



  95. // Interpret “false”, “F”, “no”, “n”, “0” as false



  96. // Interpret “true”, “T”, “yes”, “y”, “1”, “-1”, or anything else as true



  97. bool

    b =

    true

    ;

  98. std::string sup = s;


  99. for

    ( std::string::iterator p = sup.begin(); p != sup.end(); ++p )

  100. *p = toupper(*p);

    // make string all caps



  101. if

    ( sup==std::string(

    “FALSE”

    ) || sup==std::string(

    “F”

    ) ||

  102. sup==std::string(

    “NO”

    ) || sup==std::string(

    “N”

    ) ||

  103. sup==std::string(

    “0”

    ) || sup==std::string(

    “NONE”

    ) )

  104. b =

    false

    ;


  105. return

    b;

  106. }




  107. template

    <

    class

    T>

  108. T Config::Read(

    const

    std::string& key )

    const


  109. {


  110. // Read the value corresponding to key


  111. mapci p = m_Contents.find(key);


  112. if

    ( p == m_Contents.end() )

    throw

    Key_not_found(key);


  113. return

    string_as_T<T>( p->second );

  114. }




  115. template

    <

    class

    T>

  116. T Config::Read(

    const

    std::string& key,

    const

    T& value )

    const


  117. {


  118. // Return the value corresponding to key or given default value



  119. // if key is not found


  120. mapci p = m_Contents.find(key);


  121. if

    ( p == m_Contents.end() )

    return

    value;


  122. return

    string_as_T<T>( p->second );

  123. }




  124. template

    <

    class

    T>


  125. bool

    Config::ReadInto( T& var,

    const

    std::string& key )

    const


  126. {


  127. // Get the value corresponding to key and store in var



  128. // Return true if key is found



  129. // Otherwise leave var untouched


  130. mapci p = m_Contents.find(key);


  131. bool

    found = ( p != m_Contents.end() );


  132. if

    ( found ) var = string_as_T<T>( p->second );


  133. return

    found;

  134. }




  135. template

    <

    class

    T>


  136. bool

    Config::ReadInto( T& var,

    const

    std::string& key,

    const

    T& value )

    const


  137. {


  138. // Get the value corresponding to key and store in var



  139. // Return true if key is found



  140. // Otherwise set var to given default


  141. mapci p = m_Contents.find(key);


  142. bool

    found = ( p != m_Contents.end() );


  143. if

    ( found )

  144. var = string_as_T<T>( p->second );


  145. else


  146. var = value;


  147. return

    found;

  148. }




  149. template

    <

    class

    T>


  150. void

    Config::Add(

    const

    std::string& in_key,

    const

    T& value )

  151. {


  152. // Add a key with given value


  153. std::string v = T_as_string( value );

  154. std::string key=in_key;

  155. trim(key);

  156. trim(v);

  157. m_Contents[key] = v;


  158. return

    ;

  159. }






C++代码

收藏代码



  1. // Config.cpp




  2. #include “Config.h”




  3. using


    namespace

    std;



  4. Config::Config( string filename, string delimiter,

  5. string comment )

  6. : m_Delimiter(delimiter), m_Comment(comment)

  7. {


  8. // Construct a Config, getting keys and values from given file



  9. std::ifstream in( filename.c_str() );



  10. if

    ( !in )

    throw

    File_not_found( filename );


  11. in >> (*

    this

    );

  12. }



  13. Config::Config()

  14. : m_Delimiter( string(1,

    ‘=’

    ) ), m_Comment( string(1,

    ‘#’

    ) )

  15. {


  16. // Construct a Config without a file; empty


  17. }





  18. bool

    Config::KeyExists(

    const

    string& key )

    const


  19. {


  20. // Indicate whether key is found


  21. mapci p = m_Contents.find( key );


  22. return

    ( p != m_Contents.end() );

  23. }




  24. /* static */



  25. void

    Config::Trim( string& inout_s )

  26. {


  27. // Remove leading and trailing whitespace



  28. static


    const


    char

    whitespace[] =

    ” \n\t\v\r\f”

    ;

  29. inout_s.erase( 0, inout_s.find_first_not_of(whitespace) );

  30. inout_s.erase( inout_s.find_last_not_of(whitespace) + 1U );

  31. }



  32. std::ostream& operator<<( std::ostream& os,

    const

    Config& cf )

  33. {


  34. // Save a Config to os



  35. for

    ( Config::mapci p = cf.m_Contents.begin();

  36. p != cf.m_Contents.end();

  37. ++p )

  38. {

  39. os << p->first <<

    ” ”

    << cf.m_Delimiter <<

    ” ”

    ;

  40. os << p->second << std::endl;

  41. }


  42. return

    os;

  43. }



  44. void

    Config::Remove(

    const

    string& key )

  45. {


  46. // Remove key and its value


  47. m_Contents.erase( m_Contents.find( key ) );


  48. return

    ;

  49. }


  50. std::istream& operator>>( std::istream& is, Config& cf )

  51. {


  52. // Load a Config from is



  53. // Read in keys and values, keeping internal whitespace



  54. typedef

    string::size_type pos;


  55. const

    string& delim  = cf.m_Delimiter;

    // separator



  56. const

    string& comm   = cf.m_Comment;

    // comment



  57. const

    pos skip = delim.length();

    // length of separator



  58. string nextline =

    “”

    ;

    // might need to read ahead to see where value ends




  59. while

    ( is || nextline.length() > 0 )

  60. {


  61. // Read an entire line at a time


  62. string line;


  63. if

    ( nextline.length() > 0 )

  64. {

  65. line = nextline;

    // we read ahead; use it now


  66. nextline =

    “”

    ;

  67. }


  68. else


  69. {

  70. std::getline( is, line );

  71. }



  72. // Ignore comments


  73. line = line.substr( 0, line.find(comm) );



  74. // Parse the line if it contains a delimiter


  75. pos delimPos = line.find( delim );


  76. if

    ( delimPos < string::npos )

  77. {


  78. // Extract the key


  79. string key = line.substr( 0, delimPos );

  80. line.replace( 0, delimPos+skip,

    “”

    );



  81. // See if value continues on the next line



  82. // Stop at blank line, next line with a key, end of stream,



  83. // or end of file sentry



  84. bool

    terminate =

    false

    ;


  85. while

    ( !terminate && is )

  86. {

  87. std::getline( is, nextline );

  88. terminate =

    true

    ;


  89. string nlcopy = nextline;

  90. Config::Trim(nlcopy);


  91. if

    ( nlcopy ==

    “”

    )

    continue

    ;


  92. nextline = nextline.substr( 0, nextline.find(comm) );


  93. if

    ( nextline.find(delim) != string::npos )


  94. continue

    ;


  95. nlcopy = nextline;

  96. Config::Trim(nlcopy);


  97. if

    ( nlcopy !=

    “”

    ) line +=

    “\n”

    ;

  98. line += nextline;

  99. terminate =

    false

    ;

  100. }



  101. // Store key and value


  102. Config::Trim(key);

  103. Config::Trim(line);

  104. cf.m_Contents[key] = line;

    // overwrites if key is repeated


  105. }

  106. }



  107. return

    is;

  108. }


  109. bool

    Config::FileExist(std::string filename)

  110. {


  111. bool

    exist=

    false

    ;

  112. std::ifstream in( filename.c_str() );


  113. if

    ( in )

  114. exist =

    true

    ;


  115. return

    exist;

  116. }



  117. void

    Config::ReadFile( string filename, string delimiter,

  118. string comment )

  119. {

  120. m_Delimiter = delimiter;

  121. m_Comment = comment;

  122. std::ifstream in( filename.c_str() );



  123. if

    ( !in )

    throw

    File_not_found( filename );


  124. in >> (*

    this

    );

  125. }




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. port = configSettings.Read(

    “port”

    , 0);

  12. ipAddress = configSettings.Read(

    “ipAddress”

    , ipAddress);

  13. username = configSettings.Read(

    “username”

    , username);

  14. password = configSettings.Read(

    “password”

    , password);

  15. std::cout<<

    “port:”

    <<port<<std::endl;

  16. std::cout<<

    “ipAddress:”

    <<ipAddress<<std::endl;

  17. std::cout<<

    “username:”

    <<username<<std::endl;

  18. std::cout<<

    “password:”

    <<password<<std::endl;



  19. return

    0;

  20. }






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