回家无聊就写个配置文件类,通过字典树(Tire tree)来存储配置文件的信息,如果在相同节点下有相同的变量则覆盖之(具体实现请看insert函数)。
ReadConfig.h头文件
/* FileName: ReadConfig.h Author: ACb0y Create Time: 2011年2月3日 11:15:42 Last Modify Time: 2011年2月3日 12:29:05 */ #ifndef __READ_CONFIG_HEADER__ #define __READ_CONFIG_HEADER__ #define NOT_FOUND_SESSION 1 #define NOT_FOUND_VALUE 2 #define VALUE_IS_EMPTY 3 #define IS_VALUE 4 #define MAX_LINE_LENGTH 1024 #include <fstream> #include <cstring> using namespace std; //节点信息 typedef struct ReadConfigNode { ReadConfigNode * pNext[128]; bool bSessionFlag; bool bValueFlag; char * pStr; ReadConfigNode () { bSessionFlag = false; bValueFlag = false; memset(pNext, 0, sizeof(pNext)); pStr = NULL; } }ReadConfigNode; /* 类名:ReadConfig 功能:读取配置文件的内容 */ class ReadConfig { //构造函数与析构函数 private: //nothing protected: //nothing public: ReadConfig(char * strFileName); ~ReadConfig(); //属性 private: //文件输入流对象 ifstream m_In; //文件打开标记 bool m_bOpenFlag; //字典树根节点 ReadConfigNode * m_pRoot; protected: //nothing public: //nothing //服务 private: //将节点和变量信息插入Tire树中 void insert(char * strSessionName, char * strValueName, char * strValue); //查询配置文件中的某个节点下的某变量的值(在Tire tree中查询)。 int query(char * strSessionName, char * strValueName, char * strValue); //释放Tire tree动态申请的空间。 void clear(ReadConfigNode * pRoot); //获取动态申请的空间 ReadConfigNode * getNode(); //判断配置文件是否打开成功 inline bool isOpen() { return m_bOpenFlag; } //去除字符串中的空格和Tab键(前导空格和Tab键,后导空格和Tab键,中间空格和Tab键) void trim(char * str); protected: //nothing public: //获取配置文件中指定的节点下的指定变量的值,并把值保存在strValue中 bool getValue(char * strSessionName, char * strValueName, char * strValue); }; #endif
ReadConfig.cpp源文件
/* FileName: ReadConfig.cpp Author: ACb0y Create Time: 2011年2月3日 12:30:12 Last Modify Time: 2011年2月3日 23:36:30 */ #include <iostream> #include "ReadConfig.h" using namespace std; /* 函数名:ReadConfig(char * strFileName) 功能:构造函数,读取配置文件并读入Tire tree中 参数: 输入: strFileName (char *):配置文件名 输出:无 返回值:无 */ ReadConfig::ReadConfig(char * strFileName) { m_pRoot = NULL; m_In.open(strFileName); if (!m_In) { m_bOpenFlag = false; } else { m_bOpenFlag = true; } m_pRoot = getNode(); char strSessionName[MAX_LINE_LENGTH]; char strValueName[MAX_LINE_LENGTH]; char strValue[MAX_LINE_LENGTH]; char strTemp[MAX_LINE_LENGTH]; int c = 0; while (!m_In.eof()) { m_In.getline(strTemp, MAX_LINE_LENGTH); trim(strTemp); int len = strlen(strTemp); if ('[' == strTemp[0] && ']' == strTemp[len - 1]) { c = 0; for (int i = 1; i < len - 1; ++i) { strSessionName[c++] = strTemp[i]; } strSessionName[c] = 0; } else { int i = 0; c = 0; while (0 != strTemp[i] && '=' != strTemp[i]) { strValueName[c++] = strTemp[i]; ++i; } strValueName[c] = 0; ++i; c = 0; while (0 != strTemp[i]) { strValue[c++] = strTemp[i]; ++i; } strValue[c] = 0; insert(strSessionName, strValueName, strValue); } } m_In.close(); } /* 函数名:clear(ReadConfigNode * pRoot) 功能:释放Tire tree动态申请的空间 参数: 输入: pRoot(ReadConfigNode *): Tire tree的根节点 输出:无 返回:无 */ void ReadConfig::clear(ReadConfigNode * pRoot) { if (pRoot == NULL) { return ; } if (NULL != pRoot->pStr) { free(pRoot->pStr); } for (int i = 0; i < 128; ++i) { clear(pRoot->pNext[i]); } free(pRoot); } /* 函数名:~ReadConfig() 功能:析构函数 参数:无 返回:无 */ ReadConfig::~ReadConfig() { clear(m_pRoot); } /* 函数名:getNode() 功能:动态申请一个节点的空间 参数:无 返回值:pNode (ReadConfigNode *):指向申请的空间的指针 */ ReadConfigNode * ReadConfig::getNode() { ReadConfigNode * pNode = (ReadConfigNode *)malloc(sizeof(ReadConfigNode)); pNode->bSessionFlag = false; pNode->bValueFlag = false; pNode->pStr = NULL; memset(pNode->pNext, 0, sizeof(pNode->pNext)); return pNode; } /* 函数名:insert(char * strSessionName, char * strValueName, char * strValue) 功能:先Tire tree插入变量信息 参数: 输入: strSessionName(char *): 节点名 strValueName(char *): 变量名 输出: strValue(char *): 存放变量值的缓存空间 返回值:无 */ void ReadConfig::insert(char * strSessionName, char * strValueName, char * strValue) { ReadConfigNode * pCur = m_pRoot; int length = strlen(strSessionName); int index = 0; int i; for (i = 0; i < length; ++i) { index = strSessionName[i] - 31; if (NULL == pCur->pNext[index]) { pCur->pNext[index] = getNode(); } pCur = pCur->pNext[index]; } pCur->bSessionFlag = true; length = strlen(strValueName); for (i = 0; i < length; ++i) { index = strValueName[i] - 31; if (NULL == pCur->pNext[index]) { pCur->pNext[index] = getNode(); } pCur = pCur->pNext[index]; } pCur->bValueFlag = true; if (NULL != pCur->pStr) { free(pCur->pStr); pCur->pStr = NULL; } pCur->pStr = (char *)malloc(strlen(strValue) + 1); strcpy(pCur->pStr, strValue); } /* 函数:query(char * strSessionName, char * strValueName, char * strValue) 功能:从Tire tree中查询指定节点,指定变量的值,并保存到strValue中 参数: 输入: strSessionName(char *): 节点名 strValueName(char *): 变量名 输出: strValue(char *): 存储变量的值 返回值: NOT_FOUND_SESSION: 没有找到节点 NOT_FOUND_VALUE: 没有找到变量 VALUE_IS_EMPTY: 变量值为空 IS_VALUE: 找到变量的值,并存储在strValue中 */ int ReadConfig::query(char * strSessionName, char * strValueName, char * strValue) { ReadConfigNode * pCur = m_pRoot; int index = 0; bool flag = true; int i; int length = strlen(strSessionName); for (i = 0; i < length; ++i) { index = strSessionName[i] - 31; if (NULL == pCur->pNext[index]) { flag = false; break; } pCur = pCur->pNext[index]; } if (false == pCur->bSessionFlag) { strValue[0] = 0; return NOT_FOUND_SESSION; } length = strlen(strValueName); for (i = 0; i < length; ++i) { index = strValueName[i] - 31; if (NULL == pCur->pNext[index]) { flag = false; break; } pCur = pCur->pNext[index]; } if (false == pCur->bValueFlag) { strValue[0] = 0; return NOT_FOUND_VALUE; } if (pCur->pStr == NULL) { pCur->pStr[0] = 0; return VALUE_IS_EMPTY; } strcpy(strValue, pCur->pStr); return IS_VALUE; } /* 函数名:trim(char * str) 功能:去除字符串str中的空格和Tab键 参数: 输入:str (char *): 要处理的字符串 输出:无 返回值:无 */ void ReadConfig::trim(char * str) { int length = strlen(str); int c = 0; for (int i = 0; i < length; ++i) { //注释 if (str[i] == '#') { break; } //过滤空格和Tab键 if (str[i] != ' ' && str[i] != '/t') { str[c++] = str[i]; } } str[c] = 0; } /* 函数名: getValue(char * strSessionName, char * strValueName, char * strValue) 功能:获取指定节点,指定变量的值,并保存在strValue中 参数: 输入: strSeesionName (char *):节点名 strValueName (char *):变量名 输出: strValue (char *):存储变量的值 返回: true:获取到指定节点,指定变量的值 false:没有回去指定节点,指定变量的值 */ bool ReadConfig::getValue(char * strSessionName, char * strValueName, char * strValue) { int res = query(strSessionName, strValueName, strValue); if (IS_VALUE == res) { return true; } return false; }
main.cpp主控程序
#include <iostream> #include "ReadConfig.h" using namespace std; int main() { char str[MAX_LINE_LENGTH]; ReadConfig readConfig("config.ini"); readConfig.getValue("Install", "Insta", str); if (0 == str[0]) { cout << "not found" << endl; } else { cout << str << endl; } readConfig.getValue("START", "ExitAppTimeCnt", str); if (0 == str[0]) { cout << "not found" << endl; } else { cout << str << endl; } return 0; }