一个配置文件管理类
贴一个我最近写的一个配置文件的管理类,大家看看有什么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;
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
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 }