一个配置文件管理类

时间:2022-05-31 22:10:23

贴一个我最近写的一个配置文件的管理类,大家看看有什么bug。

配置文件中安linux风格用'#'做注释,数据行按照"参数名=参数值"的方法组织。

用法:

1.先 setFileName设定配置文件的文件名,或者在初始化的时候指定;

2. 调loadConfigs函数,该函数会将配置文件中合法的数据行载入到一个map中,如果文件打开失败,该函数返回false,否则返回true;

3.调用 getValue/setValue进行参数的读取和修改,在读取/修改时,函数第一个参数是要读取/修改的参数名,第二个参数是读取/修改的数值。如果指定的参数名不存在函数返回false,否则返回true。

4.如果参数被修改过,可以调用saveConfigs将修改过的参数写回配置文件。

5.以上函数如果返回false,都可以调 getErrorTex查看最近一次的错误原因。

 

代码如下:

头文文件

  1  /* ***********************************************************************
  2 
  3  About: A class to manage the config file
  4  Author: MinCheng
  5  Date: 2011/09/30
  6  File: ConfigManager.h
  7 
  8 
  9  *********************************************************************** */
 10 
 11 
 12  #pragma  once
 13 #include < string>
 14 #include <map> 
 15  using std:: string;
 16  using std::map;
 17 
 18 typedef map< string, string> ConfigListType;
 19 
 20  class ConfigManager
 21 {
 22  public:
 23     ConfigManager();
 24     ConfigManager( const  string _fileName);
 25      void setFileName( const  string _fileName);
 26      bool loadConfigs();
 27 
 28     template < class T>  bool getValue( const  char* tag,T& value);
 29     template < class T>  bool setValue( const  char* tag, T value);
 30 
 31      bool saveConfigs();
 32      const  char* getErrorTex();
 33 
 34  private:
 35      bool processLine( const  string & line,  string& tag,  string& value);
 36      void normString( string& str);
 37     template < class T>  bool convertFromString(T &value,  const std:: string &s);
 38     template < class T>  bool convertToString(T &value, std:: string &s);
 39 
 40      string fileName;
 41      bool bChanged;
 42      bool bLoaded;
 43     ConfigListType configList;
 44      string errorTex;
 45 };
 46 
 47 template< class T>
 48  bool ConfigManager::getValue( const  char* tag,T& value)
 49 {
 50      if(bLoaded== false)
 51     {
 52         errorTex= " Did not load file ";
 53          return  false;
 54     }
 55 
 56     ConfigListType::iterator it=configList.find(tag);
 57      if(it==configList.end())
 58     {
 59         errorTex= " Tag does not exist ";
 60          return  false;
 61     }
 62 
 63      return convertFromString(value,it->second);
 64 }
 65 
 66 template< class T>
 67  bool ConfigManager::setValue( const  char* tag, T value)
 68 {
 69      if(bLoaded== false)
 70     {
 71         errorTex= " Did not load file ";
 72          return  false;
 73     }
 74 
 75     ConfigListType::iterator it=configList.find(tag);
 76      if(it==configList.end())
 77     {
 78         errorTex= " Tag does not exist ";
 79          return  false;
 80     }
 81 
 82      string valueString;
 83      if(convertToString(value,valueString))
 84         configList[tag]=valueString;
 85      else
 86          return  false;
 87     bChanged= true;
 88      return  true;
 89 
 90 }
 91 
 92 
 93 template < class T> 
 94  bool ConfigManager::convertFromString(T &value,  const std:: string &s)
 95 {
 96     std::stringstream ss(s);
 97     ss >> value;
 98      if(!ss.fail())
 99          return  true;
100      else
101          return  false;
102 }
103 
104 template < class T> 
105  bool ConfigManager::convertToString(T &value, std:: string &s)
106 {
107     std::stringstream ss;
108     ss << value; 
109     s = ss.str();
110      if(!ss.fail())
111          return  true;
112      else
113          return  false;

114 }

 

cpp文件

  1  /* ***********************************************************************
  2 
  3  About: A class to manage the config file
  4  Author: MinCheng
  5  Date: 2011/09/30
  6  File: ConfigManager.cpp
  7 
  8 
  9  *********************************************************************** */
 10 
 11 #include <fstream>
 12 #include < string>
 13 #include <sstream>
 14 #include  " ConfigManager.h "
 15 
 16 
 17  using  namespace std;
 18 
 19 typedef map< string, string> ConfigListType;
 20 
 21 
 22 ConfigManager::ConfigManager()
 23 {
 24     bChanged= false;
 25     bLoaded= false;
 26 
 27 }
 28 
 29 ConfigManager::ConfigManager( const  string _fileName)
 30 {
 31      this->fileName = _fileName;
 32     bChanged= false;
 33     bLoaded= false;
 34 }
 35 
 36  void ConfigManager::setFileName( const  string _fileName)
 37 {
 38      this->fileName = _fileName;
 39 }
 40 
 41  bool ConfigManager::loadConfigs()
 42 {
 43      if(fileName.empty())
 44     {
 45         errorTex= " File name not set. ";
 46          return  false;
 47     }
 48     ifstream file(fileName.c_str());
 49      if(!file)
 50     {
 51         errorTex= " File does not exist. ";
 52          return  false;
 53 
 54     }
 55 
 56      string line;
 57      string tag;
 58      string value;
 59      while (getline(file,line))
 60     {
 61          if(line[ 0]== ' # ')
 62              continue;
 63          if(processLine(line,tag,value))
 64             configList.insert(ConfigListType::value_type(tag,value));
 65 
 66     }
 67     file.close();
 68     bLoaded= true;
 69      return  true;
 70 }
 71 
 72 
 73  bool ConfigManager::saveConfigs()
 74 {
 75      if(bChanged== false)
 76          return  true;
 77 
 78      if(fileName.empty())
 79     {
 80         errorTex= " File name not set. ";
 81          return  false;
 82     }
 83 
 84     ofstream file;
 85     file.open(fileName.c_str());
 86      ConfigListType::iterator it;
 87      for(it=configList.begin(); it!=configList.end(); it++)
 88     {
 89         file<<it->first<< " = "<<it->second<<endl;
 90 
 91     }
 92 
 93     file.close();
 94     bChanged= false;
 95 
 96      return  true;
 97     
 98 }
 99 
100  const  char* ConfigManager::getErrorTex()
101 {
102      return errorTex.c_str();
103 }
104 
105 
106 
107  bool ConfigManager::processLine( const  string & line,  string& tag,  string& value)
108 {
109      string::size_type middle=line.find_first_of( ' = ', 0);
110      if(middle== string::npos)
111          return  false;
112     tag=line.substr( 0,middle- 0);
113     value=line.substr(middle+ 1,line.length()-middle- 1);
114     normString(tag);
115     normString(value);
116      return  true;
117 }
118 
119  void ConfigManager::normString( string& str)
120 {
121      string::size_type begin=str.find_first_not_of( '   ', 0);
122      string::size_type end=str.find_last_not_of( '   ');
123      if(begin!= string::npos && end !=  string::npos)
124         str = str.substr(begin,end-begin+ 1);
125 

126 }