版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/Fish_55_66/article/details/50177865
在程序开发过程中经常要用到参数配置,通常的做法就是把参数保存在文件里。最近闲来无事,根据自己的经验总结了一个比较通用的文件配置类,以备不时之需。话不多说,直接上代码。为了防止代码占用篇幅,这里只给出配置类的头文件定义,全部代码和Demo程序下载请点击下方链接地址。
配置类头文件定义:
#pragma once
#include <map>
#include <string>
#include <fstream>
#include <sstream>
#include <algorithm>
/*/////////////////////////////////////////////////////////////////////////
** 通用配置类
/////////////////////////////////////////////////////////////////////////*/
class CGenericConfig
{
public:
CGenericConfig();
~CGenericConfig();
/// 读取配置文件
/// @param[in] fileName 配置文件全路径名称
/// @param[in] delimiter 键名和键值的分隔符
/// @param[in] comment 注释符
/// @return 读取成功返回true,失败返回false
bool ReadFile(std::string fileName, std::string delimiter = "=", std::string comment = "#");
/// 保存配置文件,文件若存在,则更新;若不存在,则新建
/// @param[in] fileName 配置文件全路径名称
void SaveFile(std::string fileName = "");
/// 获取配置项
/// @param[in] key 要读取的配置项健名
/// @param[out] value 保存读取后的配置项键值
/// @param[in] default_val 默认键值,若读取失败,配置项键值取该值
/// @return 读取成功返回true,失败返回false
template<typename T> bool GetConfig(const std::string& key, T& value) const;
template<typename T> bool GetConfig(const std::string& key, T& value, const T& default_val) const;
/// 设置配置项,健名若不存在,则新增;若存在,则更新健值
/// @param[in] key 配置项健名
/// @param[in] value 配置项键值
template<typename T> void SetConfig(const std::string& key, const T& value);
/// 删除配置项
/// @param[in] key 要删除的配置项健名
void DeleteConfig(const std::string& key);
/// 判断文件是否存在
/// @param[in] filename 配置文件全路径名称
/// @return 存在返回true,不存在返回false
bool FileExist(std::string fileName);
/// 根据健名判断配置项是否存在
/// @param[in] key 配置项健名
/// @return 存在返回true,不存在返回false
bool KeyExist(const std::string& key) const;
/// 获取配置项键名和键值的分隔符
/// @return 配置项键名和键值的分隔符
std::string GetDelimiter() const;
/// 获取注释符
/// @return 注释符
std::string GetComment() const;
/// 设置配置项键名和键值的分隔符
/// @param[in] delimiter 新的键名和键值的分隔符
/// @return 旧的键名和键值的分隔符
std::string SetDelimiter(const std::string& delimiter);
/// 设置注释符
/// @param[in] delimiter 新的注释符
/// @return 旧的注释符
std::string SetComment(const std::string& comment);
private:
/// 移除字符串两侧的空白字符
/// @param[in] str 需处理的字符串
void Trim(std::string& str);
/// 模板类型转换成std::string
/// @param[in] temp 需转换的模板参数
template<typename T> static std::string TemplateToString(const T& temp);
/// std::string转换成模板类型
/// @param[in] str 需转换的字符串
template<typename T> static T StringToTemplate(const std::string& str);
private:
/// 配置文件全路径名称
std::string m_fileName;
/// 配置项键名和键值的分隔符,默认为“=”
std::string m_delimiter;
/// 注释符,默认为“#”,即每行"#"号后面的内容都是注释
std::string m_comment;
/// 记录全部配置项的键名和键值的map表
std::map<std::string, std::string> m_mapContents;
};
测试配置文件 Config.txt 内容:
#数据库参数############################################
db_name = server #数据库名称
db_user = admin #数据库用户名
db_password = 123456 #数据库密码
#服务器参数############################################
ip_address = 192.168.100.20 #服务器IP地址
port = 30065 #服务器端口号
#程序参数###############################################
auto_login = false #是否自动登录
save_param = true #是否保存参数
应用Demo程序:
#include "GenericConfig.h"
#include <iostream>
int main()
{
std::string ConfigFile = "config.txt";
CGenericConfig configSettings;
configSettings.ReadFile(ConfigFile);
std::string dbName = "";
std::string dbUser = "";
std::string dbPsw = "";
std::string svrIP = "";
int port = 0;
bool autoLogin = false;
bool saveParam = false;
configSettings.GetConfig("db_name", dbName);
configSettings.GetConfig("db_user", dbUser);
configSettings.GetConfig("db_password", dbPsw);
configSettings.GetConfig("ip_address", svrIP);
configSettings.GetConfig("port", port);
configSettings.GetConfig("auto_login", autoLogin);
configSettings.GetConfig("save_param", saveParam);
std::cout << "db_name:" << dbName << std::endl;
std::cout << "db_user:" << dbUser << std::endl;
std::cout << "db_password:" << dbPsw << std::endl;
std::cout << "ip_address:" << svrIP << std::endl;
std::cout << "port:" << port << std::endl;
std::cout << "auto_login:" << (autoLogin?"true":"false") << std::endl;
std::cout << "saveParam:" << (saveParam ? "true" : "false") << std::endl;
system("pause");
}
程序输出:
需要注意的是,因为 SaveFile 函数的实现机制是重新编写整个配置文件,所以如果配置文件原来带有注释内容,那么在调用该函数保存配置之后,原有注释内容会消失,请务必知悉。另外,这个类支持的配置文件是比较简单的,复杂的文件配置一般都建议使用xml文件,这里顺便推荐一个 C++ 操作xml文件的类:TinyXML2。
提示:以上代码和Demo程序在Visual Studio 2013编译通过。