github sampleini库下载链接: https://github.com/brofield/simpleini
下载后只需一下三个文件即可:
配置文件格式:采用以下格式;
1. 加载配置文件前重要设置
/*设置是否使用utf8编码作为加载/保存; 在ini数据被加载后不可设置; 默认true;*/
void SetUnicode(bool a_bIsUtf8 = true) {
if (!m_pData) m_bStoreIsUtf8 = a_bIsUtf8;
};
/*是否允许使用多个相同的key;
若为true; 则:
[section]
test = value1;
test = value2;
上面两个key相同,value不同可被允许设置;
若为false;
[section]
test = value2; //value1 为上次值,被覆盖;
*/
void SetMultiKey(bool a_bAllowMultiKey = true) {
m_bAllowMultiKey = a_bAllowMultiKey;
}
/*是否允许数据value跨越文件中的多行*/
void SetMultiLine(bool a_bAllowMultiLine = true) {
m_bAllowMultiLine = a_bAllowMultiLine;
}
/*写入键/值时是否应该在等号周围添加空格;
若为true; 则 key = value 等号两边有空格;
若为false;则 key=value 等号两边无空格;
*/
void SetSpaces(bool a_bSpaces = true) {
m_bSpaces = a_bSpaces;
}
/*是否应该识别或解析单行value中的引号;*/
void SetQuotes(bool a_bParseQuotes = true) {
m_bParseQuotes = a_bParseQuotes;
}
//默认状态如下;
printf("IsUnicode = %d \n",conf.IsUnicode());//0
printf("IsMultiKey = %d \n",conf.IsMultiKey());//0
printf("IsMultiLine = %d \n",conf.IsMultiLine());//0
printf("UsingSpaces = %d \n",conf.UsingSpaces());//1
printf("UsingQuotes = %d \n",conf.UsingQuotes());//0
2. 加载数据
//参数为文件路径
SI_Error LoadFile(
const char * a_pszFile
);
(1) 该函数有很多同名函数(重载函数);
(2) 该函数加载是将配置文件从磁盘上加载到内存中; 接下来的很多操作如:setValue等仅仅是改变内存中的数据;在系统掉电是不会保存到磁盘上的; 在内存中操作的目的就是快;
(3) 要想将内存中改变的数据保存到磁盘,需要调用 saveFile()函数将内存中的数据保存到磁盘上;
3. 获取配置信息
/*获取所有[section]名字;
返回的名字存储在a_names中;
有定义: typedef std::list<Entry> TNamesDepend; 可知实际为list;
*/
void GetAllSections(
TNamesDepend & a_names
) const;
/*检索所有[section]中的key和val键值对;*/
const TKeyVal * GetSection(
const SI_CHAR * a_pSection
) const;
/*获取[section]中的所有key值,保存到 a_names中; */
bool GetAllKeys(
const SI_CHAR * a_pSection,
TNamesDepend & a_names
) const;
/*根据section,key获取对应的value*/
const SI_CHAR * GetValue(
const SI_CHAR * a_pSection,
const SI_CHAR * a_pKey,
const SI_CHAR * a_pDefault = NULL,
bool * a_pHasMultiple = NULL
) const;
//根据section,key获取bool类型,double类型,long类型,
bool GetBoolValue(
const SI_CHAR * a_pSection,
const SI_CHAR * a_pKey,
bool a_bDefault = false,
bool * a_pHasMultiple = NULL
) const;
double GetDoubleValue(
const SI_CHAR * a_pSection,
const SI_CHAR * a_pKey,
double a_nDefault = 0,
bool * a_pHasMultiple = NULL
) const;
bool GetBoolValue(
const SI_CHAR * a_pSection,
const SI_CHAR * a_pKey,
bool a_bDefault = false,
bool * a_pHasMultiple = NULL
) const;
4. 修改(内存)内容
/*设置值
参数1: section字符串
参数2: key字符串
参数3: value字符串
*/
SI_Error SetValue(
const SI_CHAR * a_pSection,
const SI_CHAR * a_pKey,
const SI_CHAR * a_pValue,
const SI_CHAR * a_pComment = NULL,
bool a_bForceReplace = false
)
SI_Error SetLongValue(
const SI_CHAR * a_pSection,
const SI_CHAR * a_pKey,
long a_nValue,
const SI_CHAR * a_pComment = NULL,
bool a_bUseHex = false,
bool a_bForceReplace = false
);
SI_Error SetDoubleValue(
const SI_CHAR * a_pSection,
const SI_CHAR * a_pKey,
double a_nValue,
const SI_CHAR * a_pComment = NULL,
bool a_bForceReplace = false
);
SI_Error SetBoolValue(
const SI_CHAR * a_pSection,
const SI_CHAR * a_pKey,
bool a_bValue,
const SI_CHAR * a_pComment = NULL,
bool a_bForceReplace = false
);
调用了上述设置key对应的值后并不能修改磁盘上的内容;原因是设置的内容是loadFile到内存中的数据;
需要使用 saveFile() 函数才能真正将内存中的数据保存到磁盘上;
//内部调用了继承了OutputWriter类的FileWriter类,并调用了write函数;
FILE *fp = fopen("./config.ini","w+");
conf.SaveFile(fp);
fclose(fp);
或者
//其内部也是将文件用fopen打开,然后调用saveFile(FILE *);
conf.SaveFile("./config.ini");
5. 删除节点/键/值
//将会删掉[section]为"server"的节点;
conf.Delete("server", NULL);
//仅删掉[section]为type, key为"_int"的键和值;
conf.Delete("type", "_int");
//删除[section]为"type",key为"_long"的键和值;
conf.DeleteValue("type", "_long", NULL);
//删除[section]为"type",key为"_bool"的键和值(不管值是否能够对应都会被删);
conf.DeleteValue("type", "_bool", "false");
6. 测试示例
#include <iostream>
#include "SimpleIni.h"
#include <list>
using namespace std;
int main()
{
SI_Error err;
CSimpleIniA conf;
conf.SetUnicode(true);//设置为utf8编码;
//从磁盘加载到内存中;
err = conf.LoadFile("./config.ini");
if(SI_OK != err){
cout << "load file err" << endl;
return -1;
}
CSimpleIniA::TNamesDepend secNames;
//获取所有section
conf.GetAllSections(secNames);
//遍历list
for(const auto &iter : secNames){
cout << "[section] = " << iter.pItem << endl;
//通过section名字获取键值对;
const CSimpleIniA::TKeyVal *pkeyVal = conf.GetSection(iter.pItem);
if(nullptr != pkeyVal){
for(const auto &iter : *pkeyVal){
cout << iter.first.pItem << " = " << iter.second << endl;
}
}
}
CSimpleIniA::TNamesDepend keyNames;
if(true == conf.GetAllKeys("message", keyNames)){ //发现对应的section名,返回true
printf("\n");
for(const auto &iter : keyNames){
cout << "keyName = " << iter.pItem << endl;
}
}
CSimpleIniA::TNamesDepend valNames;
if(true == conf.GetAllValues("server", "ip", valNames)){
printf("\n");
for(const auto &iter : valNames){
cout << "valName = " << iter.pItem << endl;
}
}
const char *val = conf.GetValue("server", "port");
if(val)
cout << "val = " << val << endl;
printf("bool = %d \n",conf.GetBoolValue("type", "_bool"));
printf("_int = %ld \n",conf.GetLongValue("type", "_int"));
printf("_double = %lf \n",conf.GetDoubleValue("type", "_double"));
printf("_long = %ld \n",conf.GetLongValue("type", "_long"));
err = conf.SetValue("type", "_bool", "false");
if(err == SI_UPDATED){
printf("update bool ok \n");
}
conf.SetLongValue("type", "_int", 666);
conf.SetDoubleValue("type", "_double", 20.222);
conf.Delete("server", NULL);//将会删掉[section]为"server"的节点;
conf.Delete("type", "_int");//删掉[section]为type, key为"_int"的键和值;
conf.DeleteValue("type", "_long", NULL); //删除[section]为"type",key为"_long"的键和值;
conf.DeleteValue("type", "_bool", "false");//删除[section]为"type",key为"_bool"的键和值(不管值是否能够对应都会被删);
//才能完成真正的写;
#if 0 //ok
FILE *fp = fopen("./config.ini","w+");
conf.SaveFile(fp);
fclose(fp);
#else
conf.SaveFile("./config.ini");//其内部也是将文件用fopen打开,然后调用saveFile(FILE *);
#endif
return 0;
}
实现了ini配置文件的增删改查; 而且可动态增加配置;