一杯清酒邀明月
天下本无事,庸人扰之而烦耳。

  最近在学习时,发现自己还不会操作ini文件,想着以前工作时接触到的项目或多或少都要用到ini文件去保存初始化程序的数据;所以赶紧去网上搜索以下C/C++操作ini文件都有些什么库可以玩玩;搜索到有:

  1. inih:这是C语言小巧的库,更适合嵌入式开发;

  2. iniparser:这是C语言的库,挺方便使用的,开源,两个.h文件和两个.c文件,但只能在Linux中使用;

  3. simpleini:这是C++的库,挺方便使用的,跨平台,开源,就两个.h文件和一个.c文件,且支持中文;

  所以最后我选择了simpleini这个库去学习使用!

一、介绍

1. ini介绍

  ini文件由 [section] 节点 和 key 键 和 value 值 构成。

  例如一个简单的ini文件如下所示:

 1 [message]
 2 name = 张三
 3 age = 25
 4 height = 173.2
 5  
 6 ; 这是一个注释
 7  
 8 [server]
 9 ip = 127.0.0.1
10 port = 6666

  message就是节点,节点下方就是它的键和值;server也是一个节点。

  如果需要注释,使用英文分号 ' ; ' 即可。

2. simpleini介绍

  一个跨平台库,提供了一个简单的API来读取和写入ini风格的配置文件。它支持ASCII、MBCS和Unicode格式的数据文件。它被明确设计为可移植到任何平台,并已在Windows, WinCE和Linux上进行了测试。使用MIT`许可证作为开源和免费发布.

功能概述

  • MIT许可允许在所有软件中免费使用(包括GPL和商业软件)
  • 多平台(Windows 95到Windows 10、Windows CE、Linux、Unix)
  • 加载和保存ini风格的配置文件
  • 在所有平台上,配置文件可以使用任何换行格式
  • 对文件格式的自由接受
  • 没有section的键/值,没有值的键
  • 删除部分、键和值周围的空白
  • 支持多行值(嵌入换行字符的值)
  • 可选支持同名的多个键
  • 可选的不区分大小写的节和键(仅针对ASCII字符)
  • 在文件加载时以相同的顺序保存部分和键
  • 尽可能保留文件、节和键上的注释
  • 同时支持char或wchar_t编程接口
  • 同时支持MBCS(系统区域设置)和UTF-8文件编码
  • 在Linux/Unix上,系统区域设置不需要是UTF-8才能加载UTF-8文件
  • 在节、键、值和注释中支持非ascii字符
  • 通过用户编写的转换器类支持非标准字符类型或文件编码
  • 支持以编程方式添加/修改值
  • 在大多数编译器中应该编译没有警告

二、下载

  GitHub链接:https://github.com/brofield/simpleini
  GitHub - brofield/simpleini: Cross-platform C++ library providing a simple API to read and write INI-style configuration files

 下载后解压

 这三个文件可在 Window 或 Linux 环境去使用!

三、使用

以下介绍的用法,Linux和Window环境均可使用! 

 包含头文件:

#include "SimpleIni.h"

#define FILE_NAME    "./test1.ini" 

test1.ini内容如下:

1. 加载ini文件

 1 // 定义ini文档对象
 2 CSimpleIniA ini;
 3  
 4 // 加载ini文件
 5 SI_Error rc;
 6 rc = ini.LoadFile(FILE_NAME);    // 另一种方式:SI_Error LoadFile(FILE * a_fpFile);
 7 if (rc < 0) { 
 8     printf("加载 %s ini 文件失败!\n", FILE_NAME);
 9     return -1;
10 }

rc返回值有以下这些:

 1 using SI_Error = int;
 2  
 3 constexpr int SI_OK = 0;        //!< No error
 4 constexpr int SI_UPDATED = 1;   //!< An existing value was updated
 5 constexpr int SI_INSERTED = 2;  //!< A new value was inserted
 6  
 7 // note: test for any error with (retval < 0)
 8 constexpr int SI_FAIL = -1;     //!< Generic failure
 9 constexpr int SI_NOMEM = -2;    //!< Out of memory error
10 constexpr int SI_FILE = -3;     //!< File error (see errno for detail error)

2. 简单配置

1 // 设置INI数据的存储格式,参数为true时保存为UTF-8格式,否则为本地编码格式
2 ini.SetUnicode(true);
3  
4 // 是否允许一个关键字对应多个值,默认为允许;若不允许,则将最后一个值作为此关键字关联的值
5 ini.SetMultiKey(false);

3. 增

 SetValue

参数一:节点

参数二:键

参数三:值

返回值:SI_Error (也就是int类型)

1). 添加一个新的节点(section)

1 // 添加一个新的 section
2 rc = ini.SetValue("section1", nullptr, nullptr);
3 if (rc < 0) { 
4     printf("添加section1失败!\n");
5     return -1;
6 }

2). 添加一个新的 key和value

 1 // 添加一个新的 key和value
 2 rc = ini.SetValue("section1", "name", "张三");
 3 if (rc < 0) {
 4     printf("添加name失败!\n");
 5     return -1;
 6 }
 7 //const char *name = ini.GetValue("section1", "name", "");
 8 //printf("name = %s\n", name);
 9  
10 ini.SetValue("section1", "age", "24");
11 ini.SetValue("section1", "sex", "");

注意:如果name存在,则会将name键(key)对应的值(value)修改为张三;

  还可以使用SetLongValue、SetDoubleValue、SetBoolValue去添加:

1 ini.SetLongValue("server", "length", 173);
2 ini.SetDoubleValue("server", "weight", 53.5);
3 ini.SetBoolValue("server", "vip", true);

4. 改

SetValue

参数一:节点

参数二:键

参数三:值

返回值:SI_Error (也就是int类型)

1). 修改值(value)

1 // 修改value,如果键(name)不存在则添加该 key和value
2 rc = ini.SetValue("section1", "name", "李四");
3 if (rc < 0) { 
4     printf("修改name失败!\n");
5     return -1;
6 }
7 //const char *name = ini.GetValue("section1", "name");
8 //printf("name = %s\n", name);

注意:如果要修改的值对应的键不存在,则会添加改键和值到section1节点中! 

 貌似无法修改节点(section) 和 键(key),我没有找到相关的api。。。

 还可以使用SetLongValue、SetDoubleValue、SetBoolValue去添加:

1 ini.SetLongValue("server", "length", 1000);
2 ini.SetDoubleValue("server", "weight", 66.66);
3 ini.SetBoolValue("server", "vip", false);

5. 删

Delete

参数一:节点

参数二:键

返回值:bool 

bool done = false; 

1). 删除 key 和 value

1 // 删除 key
2 done = ini.Delete("section1", "name");
3 if (false == done) {
4     printf("删除 section1 - name 失败!\n");
5     return -1;
6 }

2). 当最后一个key也被删除掉后,section1也会被删除

1 // 如果最后一个key也被删除了,那么section也会被一起删除掉
2 bool deleteSectionIfEmpty = true;
3 done = ini.Delete("section1", "age", deleteSectionIfEmpty);
4 if (false == done) {
5     printf("删除 section1 - age 失败!\n");
6     return -1;
7 }

此时section1中还由两个key,随意上面的代码执行后只会将age给删除掉,并不会也把section1删掉;

 如果将Delete的第三个参数值true去删除sex,那么section1也会一并删掉!

ini.Delete("section1", "sex", true);

 将section1还原到一开始的的样子 ,方便下面第3点操作删除

3). 删除整个节点(section)和其下的所有键(key) 

1 // 删除整个section和其中的所有键
2 done = ini.Delete("section1", nullptr);
3 if (false == done) {
4     printf("删除整个section和其中的所有键 失败 !\n");
5     return -1;
6 }

执行如上代码,就会将刚刚还原的section1都给删除掉!

6. 查

GetValue

参数一:节点

参数二:键

参数三:如果没找到,返回参数三指定的默认值

返回值:const char *

1). 将下图中的ini文件内容读取打印显示

 1 int _int = std::stoi(ini.GetValue("section", "_int", "-1"));
 2 printf("_int = %d\n", _int);
 3  
 4 long long _long = std::stoll(ini.GetValue("section", "_long", "-1"));
 5 printf("_long = %lld\n", _long);
 6  
 7 double _double = std::stod(ini.GetValue("section", "_double", "0.0"));
 8 printf("_double = %lf\n", _double);
 9  
10 float _float = std::stof(ini.GetValue("section", "_float", "0.0"));
11 printf("_float = %f\n", _float);
12  
13 bool _bool = ini.GetBoolValue("section", "_bool", false);
14 printf("_bool = %s\n", _bool ? "true" : "false");
15  
16 std::string _string = ini.GetValue("section", "_string", "");
17 printf("_string = %s\n", _string.c_str());
18  
19 std::string _string2 = ini.GetValue("section", "_string2", "");
20 printf("_string2 = %s\n", _string2.c_str());
21  
22 char _char = ini.GetValue("section", "_char", "")[0];
23 printf("_char = %c\n", _char);
24  
25 std::string ip = ini.GetValue("server", "ip", "0.0.0.0");
26 printf("ip = %s\n", ip.c_str());
27  
28 int port = std::stoi(ini.GetValue("server", "port", "-1"));
29 printf("port = %d\n", port);
30  
31 std::string name1 = ini.GetValue("server", "name", "");
32 printf("name = %s\n", name1.c_str());

 还可以使用GetLongValue、GetDoubleValue、GetBoolValue去查:

1 int lenght = ini.GetLongValue("server", "length", -1);
2 double weight = ini.GetDoubleValue("server", "weight", -1);
3 bool vip = ini.GetBoolValue("server", "vip", false);

2). 遍历ini文件的所有内容

GetAllSections:获取所有节点,参数一引用返回list链表;

GetSection:根据参数字符串,获取节点,返回multimap容器;

 1 CSimpleIniA::TNamesDepend sections;
 2 // get all sections
 3 ini.GetAllSections(sections);    
 4 // 遍历所有 section 的 key 和 value
 5 for (const auto &it : sections) {
 6     const CSimpleIniA::TKeyVal *pKeyVal = ini.GetSection(it.pItem);
 7     if (nullptr != pKeyVal) {
 8         for (const auto& it : *pKeyVal) {
 9             std::cout << it.first.pItem << " = " << it.second << std::endl;
10         }
11     }
12 }

3). 遍历所有节点(section)

1 CSimpleIniA::TNamesDepend sections1;
2 // 获取所有section
3 ini.GetAllSections(sections1);
4 // 遍历所有 sections
5 for (const auto &it : sections1) {
6     std::cout << it.pItem << std::endl;
7 }

4). 遍历指定节点的键(key)

GetAllKeys:获取所有键,参数二引用返回list链表; 

1 CSimpleIniA::TNamesDepend keys;
2 // get all keys in a section
3 ini.GetAllKeys("section", keys);    
4 // 遍历 section 指定的所有 key
5 for (const auto &it : keys) {
6     std::cout << it.pItem << std::endl;
7 }

5). 获取一个键对应多个值 

首先,ini.SetMultiKey(true);得设置为true,否则只会获取到最后一个值,其他会被删除掉;

在ini文件中的server节点添加多几个name键

  使用以下代码获取:

1 CSimpleIniA::TNamesDepend values;
2 // 获取 key 所对应的多个 value;ini.SetMultiKey(true);一定要设置为true,
3 // 否则就只会获取到最后一个,其他删除
4 ini.GetAllValues("server", "name", values);
5 // 遍历一个 key 对应多个 value;
6 for (const auto &it : values) {
7     printf("name = %s\n", it.pItem);    
8 }

6). 获取指定节点(section)里有多少键值

1 // 获取section里有多少值
2 int size = ini.GetSectionSize("section");
3 printf("section 的 key 个数:%d\n", size);

7. 保存

注意:以上增、删、改,只有执行保存代码后,才会在文件做出相应的修改!

1). 保存到文件 

1 /* 保存到文件中 */
2 rc = ini.SaveFile(FILE_NAME);
3 if (rc < 0) { 
4     printf("保存 %s ini文件失败\n", FILE_NAME);
5 }

2). 保存到C++字符串

1 std::string strIni = "";
2 ini.Save(strIni);
3 printf("%s\n", strIni.c_str());

8. 中文乱码问题

window环境写入或者读取中文有乱码现象,将文件编码改成ANSI编码即可!

可以使用notepad++去修改,如下图:

Linux环境出现中文乱码问题,那就新建一个文件,然后再手动敲上需要的信息即可,例如 touch test1.ini 或 vim test1.ini

记得,千万别从从Window拷贝进Linux中,文件中是不会显示出乱码,但是读取写入时会有乱码!

我遇到的乱码问题,通过上面的方法就可以解决了!

四、封装

  可以根据自己项目的具体需求去封装成方便调用的接口去使用!

  例如我下面的用法:

  configdef.h

  这个是定义结构体的头文件,从ini文件中读取的数据都存放在结构体中!

 1 #ifndef _COMMON_CONFIGDEF_H_
 2 #define _COMMON_CONFIGDEF_H_
 3  
 4 #include <string>
 5  
 6 typedef struct st_env_config {
 7     // 对应ini文件
 8  
 9     // section
10     int _int;
11     long _long;
12     double _double;
13     float _float;
14     bool _bool;
15     std::string _string;
16     char _char;
17  
18     // server
19     std::string _ip;
20     unsigned short _port;
21  
22  
23  
24     // 构造函数
25     st_env_config() { }
26     st_env_config(int _int, long _long, double _double, float _float, bool _bool, std::string _string, char _char, std::string _ip, unsigned short _port) {
27         this->_int = _int;
28         this->_long = _long;
29         this->_double = _double;
30         this->_float = _float;
31         this->_bool = _bool;
32         this->_string = _string;
33         this->_char = _char;
34  
35         this->_ip = _ip;
36         this->_port = _port;
37     }
38     
39     // 赋值运算符重载
40     st_env_config &operator=(const st_env_config &config) {
41         if (this != &config) {
42             this->_int = config._int;
43             this->_long = config._long;
44             this->_double = config._double;
45             this->_float = config._float;
46             this->_bool = config._bool;
47             this->_string = config._string;
48             this->_char = config._char;
49  
50             this->_ip = _ip;
51             this->_port = _port;
52         }
53         
54         return *this;
55     }
56     
57 }_st_env_config;
58  
59 #endif    // _COMMON_CONFIGDEF_H_

iniconfig.h

这个是封装simpleini的头文件

 1 #ifndef _COMMON_INICONFIG_H_
 2 #define _COMMON_INICONFIG_H_
 3  
 4 #include <string>
 5  
 6 #include "configdef.h"
 7  
 8 #include "../simpleini/SimpleIni.h"
 9  
10  
11  
12 class Iniconfig {
13 public:
14     Iniconfig();
15     Iniconfig(const std::string &path, st_env_config &config);
16     ~Iniconfig();
17     
18     // 加载ini文件
19     bool loadfile(const std::string &path);
20     // 保存ini文件
21     bool saveFile(const std::string &fileName);
22  
23     // 设置INI数据的存储格式,参数为true时保存为UTF-8格式,否则为本地编码格式
24     void setUnicode(const bool utf8 = true);
25     // 是否允许一个关键字对应多个值,默认为允许;若不允许,则将最后一个值作为此关键字关联的值,其他删除
26     void setMultiKey(const bool multKey = false);
27  
28     // 获取ini文件中的数据,保存到结构体中
29     bool getData(st_env_config &config);
30  
31     // 获取ini文件字符串
32     std::string getIniStr();
33  
34     // 添加一个新的section
35     bool addSection(const std::string &section);
36     // 添加一个新的key和value,value可以默认为空
37     bool addValue(const std::string &section, const std::string &key, const std::string &value = "");
38     bool addLongValue(const std::string &section, const std::string &key, const long value = 0);
39     bool addDoubleValue(const std::string &section, const std::string &key, const double value = 0.0);
40     bool addBoolValue(const std::string &section, const std::string &key, const bool value = false);
41  
42     // 修改value,如果key不存在,则会创建key和value
43     bool setValue(const std::string &section, const std::string &key, const std::string &value);
44     bool setLongValue(const std::string &section, const std::string &key, const long value = 0);
45     bool setDoubleValue(const std::string &section, const std::string &key, const double value = 0.0);
46     bool setBoolValue(const std::string &section, const std::string &key, const bool value = false);
47  
48     // 删除key
49     bool deleteKey(const std::string &section, const std::string &key);
50     // 删除key,如果最后一个key也被删除了,那么section也会被一起删除掉
51     bool deleteKeys(const std::string &section, const std::string &key, const bool deleteSectionIfEmpty = true);
52     // 删除section,整个section和其中的所有键值
53     bool deleteSection(const std::string &section);
54  
55  
56     // 获取string类型值
57     std::string getValue(const std::string &section, const std::string &key, const std::string &defualtValue = "");
58     // 获取char类型值
59     char getValueC(const std::string &section, const std::string &key, const char &defualtValue = '\0');
60     // 获取long、int、short类型
61     long getLongValue(const std::string &section, const std::string &key, const short &defualtValue = -1);
62     // 获取double、float类型
63     double getDoubleValue(const std::string &section, const std::string &key, const double &defualtValue = 0.0);
64     // 获取bool类型
65     bool getBoolValue(const std::string &section, const std::string &key, const bool &defualtValue = false);
66  
67     // 获取section里有多少值
68     int getSectionSize(const std::string &section);
69  
70     // 遍历所有
71     void printAll();
72     
73 private:
74     bool _isloaded;        // 是否已经加载
75     CSimpleIniA _ini;    // ini操作对象
76 };
77  
78 #endif    // _COMMON_INICONFIG_H_

iniconfig.cpp

这个是封装simpleini的cpp文件内容

  1 #include "iniconfig.h"
  2  
  3 #include <stdio.h>
  4 #include <iostream>
  5  
  6  
  7 Iniconfig::Iniconfig() : _isloaded(false) {
  8     _ini.SetUnicode(true);        // 使用utf8编码
  9     _ini.SetMultiKey(false);    // 不允许一个key对应多个value
 10  
 11     _isloaded = false;
 12 }
 13  
 14 Iniconfig::Iniconfig(const std::string & path, st_env_config &config) {
 15     _ini.SetUnicode(true);        // 使用utf8编码
 16     _ini.SetMultiKey(false);    // 不允许一个key对应多个value
 17     
 18     _isloaded = false;
 19  
 20     SI_Error rc;
 21     rc = _ini.LoadFile(path.c_str());    // 另一种方式:SI_Error LoadFile(FILE * a_fpFile);
 22     if (rc < 0) {
 23         printf("加载 %s ini 文件失败!\n", path.c_str());
 24         _isloaded = false;
 25         return;
 26     } 
 27  
 28     int _int = getLongValue("section", "_int", -1);
 29     long _long = getLongValue("section", "_long", -1);
 30     double _double = getDoubleValue("section", "_double", 0.0);
 31     float _float = getDoubleValue("section", "_float", 0.0);
 32     bool _bool = getBoolValue("section", "_bool", false);
 33     std::string _string = getValue("section", "_string", "");
 34     char _char = getValueC("section", "_char", '\0');
 35     std::string ip = getValue("server", "ip", "0.0.0.0");
 36     unsigned short port = getLongValue("section", "port", -1);
 37  
 38     config = st_env_config(_int, _long, _double, _float, _bool, _string, _char, ip, port);
 39  
 40     _isloaded = true;
 41 }
 42  
 43 Iniconfig::~Iniconfig() {
 44     
 45 }
 46  
 47 // 加载ini文件
 48 bool Iniconfig::loadfile(const std::string &path) {
 49    
 50     if (false == _isloaded) {
 51         SI_Error rc;
 52         rc = _ini.LoadFile(path.c_str());    // 另一种方式:SI_Error LoadFile(FILE * a_fpFile);
 53         if (rc < 0) {
 54             printf("加载 %s ini 文件失败!\n", path.c_str());
 55             _isloaded = false;
 56             return _isloaded;
 57         }
 58  
 59         _isloaded = true;
 60  
 61     } 
 62        
 63     return _isloaded;
 64 }
 65  
 66 bool Iniconfig::saveFile(const std::string & fileName) {
 67  
 68     SI_Error rc = _ini.SaveFile(fileName.c_str());
 69     if (rc < 0) {
 70         printf("保存 %s ini文件失败\n", fileName.c_str());
 71         return false;
 72     }
 73  
 74     _isloaded = false;
 75  
 76     return true;
 77 }
 78  
 79 void Iniconfig::setUnicode(const bool utf8) {
 80     _ini.SetUnicode(utf8);        // true:使用utf8编码
 81 }
 82  
 83 void Iniconfig::setMultiKey(const bool multKey) {
 84     _ini.SetMultiKey(multKey);    // false:不允许一个key对应多个value
 85 }
 86  
 87 bool Iniconfig::getData(st_env_config & config) {
 88     if (true == _isloaded) {
 89         int _int = getLongValue("section", "_int", -1);
 90         long _long = getLongValue("section", "_long", -1);
 91         double _double = getDoubleValue("section", "_double", 0.0);
 92         float _float = getDoubleValue("section", "_float", 0.0);
 93         bool _bool = getBoolValue("section", "_bool", false);
 94         std::string _string = getValue("section", "_string", "");
 95         char _char = getValueC("section", "_char", '\0');
 96         std::string ip = getValue("server", "ip", "0.0.0.0");
 97         unsigned short port = getLongValue("section", "port", -1);
 98  
 99         config = st_env_config(_int, _long, _double, _float, _bool, _string, _char, ip, port);
100  
101         return true;
102     }
103  
104     return false;
105 }
106  
107 std::string Iniconfig::getIniStr() {
108     std::string str = "";
109  
110     if (true == _isloaded) {
111         SI_Error rc = _ini.Save(str);
112         if (rc < 0) {
113             printf("获取ini文件字符串失败!\n");
114             str = "";
115         }
116     }
117  
118     return str;
119 }
120  
121 bool Iniconfig::addSection(const std::string & section) {
122  
123     if (false == _isloaded) { return false; }
124  
125     SI_Error rc = _ini.SetValue(section.c_str(), nullptr, nullptr);
126     if (rc < 0) {
127         printf("添加 %s 节点失败!\n", section.c_str());
128         return false;
129     }
130  
131     return true;
132 }
133  
134 bool Iniconfig::addValue(const std::string & section, const std::string & key, const std::string & value) {
135     if (false == _isloaded) { return false; }
136  
137     SI_Error rc = _ini.SetValue(section.c_str(), key.c_str(), value.c_str());
138     if (rc < 0) {
139         printf("添加 %s key失败!\n", key.c_str());
140         return false;
141     }
142  
143     return true;
144 }
145  
146 bool Iniconfig::addLongValue(const std::string & section, const std::string & key, const long value) {
147     if (false == _isloaded) { return false; }
148  
149     SI_Error rc = _ini.SetLongValue(section.c_str(), key.c_str(), value);
150     if (rc < 0) {
151         printf("添加 %s key失败!\n", key.c_str());
152         return false;
153     }
154  
155     return true;
156 }
157  
158 bool Iniconfig::addDoubleValue(const std::string & section, const std::string & key, const double value) {
159     if (false == _isloaded) { return false; }
160  
161     SI_Error rc = _ini.SetDoubleValue(section.c_str(), key.c_str(), value);
162     if (rc < 0) {
163         printf("添加 %s key失败!\n", key.c_str());
164         return false;
165     }
166  
167     return true;
168 }
169  
170 bool Iniconfig::addBoolValue(const std::string & section, const std::string & key, const bool value) {
171     if (false == _isloaded) { return false; }
172  
173     SI_Error rc = _ini.SetBoolValue(section.c_str(), key.c_str(), value);
174     if (rc < 0) {
175         printf("添加 %s key失败!\n", key.c_str());
176         return false;
177     }
178  
179     return true;
180 }
181  
182 bool Iniconfig::setValue(const std::string & section, const std::string & key, const std::string & value) {
183     if (false == _isloaded) { return false; }
184  
185     SI_Error rc = _ini.SetValue(section.c_str(), key.c_str(), value.c_str());
186     if (rc < 0) {
187         printf("修改 %s value失败!\n", value.c_str());
188         return false;
189     }
190  
191     return true;
192 }
193  
194 bool Iniconfig::setLongValue(const std::string & section, const std::string & key, const long value) {
195     if (false == _isloaded) { return false; }
196  
197     SI_Error rc = _ini.SetLongValue(section.c_str(), key.c_str(), value);
198     if (rc < 0) {
199         printf("修改 %s key失败!\n", key.c_str());
200         return false;
201     }
202  
203     return true;
204 }
205  
206 bool Iniconfig::setDoubleValue(const std::string & section, const std::string & key, const double value) {
207     if (false == _isloaded) { return false; }
208  
209     SI_Error rc = _ini.SetDoubleValue(section.c_str(), key.c_str(), value);
210     if (rc < 0) {
211         printf("修改 %s key失败!\n", key.c_str());
212         return false;
213     }
214  
215     return true;
216 }
217  
218 bool Iniconfig::setBoolValue(const std::string & section, const std::string & key, const bool value) {
219     if (false == _isloaded) { return false; }
220  
221     SI_Error rc = _ini.SetBoolValue(section.c_str(), key.c_str(), value);
222     if (rc < 0) {
223         printf("修改 %s key失败!\n", key.c_str());
224         return false;
225     }
226  
227     return true;
228 }
229  
230 bool Iniconfig::deleteKey(const std::string & section, const std::string & key) {
231     if (false == _isloaded) { return false; }
232  
233     bool done = false;
234  
235     // 删除 key
236     done = _ini.Delete(section.c_str(), key.c_str());
237     if (false == done) {
238         printf("删除 %s - %s 失败!\n", section.c_str(), key.c_str());
239         return false;
240     }
241  
242     return true;
243 }
244  
245 bool Iniconfig::deleteKeys(const std::string & section, const std::string & key, const bool deleteSectionIfEmpty) {
246     if (false == _isloaded) { return false; }
247  
248     bool done = false;
249  
250     done = _ini.Delete(section.c_str(), key.c_str(), deleteSectionIfEmpty);
251     if (false == done) {
252         printf("删除 %s - %s 失败!\n", section.c_str(), key.c_str());
253         return false;
254     }
255  
256     return true;
257 }
258  
259 bool Iniconfig::deleteSection(const std::string & section) {
260     if (false == _isloaded) { return false; }
261  
262     bool done = false;
263  
264     done = _ini.Delete(section.c_str(), nullptr);
265     if (false == done) {
266         printf("删除整个 %s 和其下的所有 键 失败 !\n", section.c_str());
267         return false;
268     }
269  
270     return true;
271 }
272  
273 std::string Iniconfig::getValue(const std::string & section, const std::string & key, const std::string & defualtValue) {
274     if (false == _isloaded) { return ""; }
275  
276     return  _ini.GetValue(section.c_str(), key.c_str(), defualtValue.c_str());
277 }
278  
279 char Iniconfig::getValueC(const std::string & section, const std::string & key, const char & defualtValue) {
280     if (false == _isloaded) { return '\0'; }
281  
282     std::string str = std::to_string(defualtValue);
283     return  _ini.GetValue(section.c_str(), key.c_str(), str.c_str())[0];
284 }
285  
286 long Iniconfig::getLongValue(const std::string & section, const std::string & key, const short & defualtValue) {
287     if (false == _isloaded) { return -1; }
288  
289     return  _ini.GetLongValue(section.c_str(), key.c_str(), defualtValue);
290 }
291  
292 double Iniconfig::getDoubleValue(const std::string & section, const std::string & key, const double & defualtValue) {
293     if (false == _isloaded) { return -1.0; }
294  
295     return  _ini.GetDoubleValue(section.c_str(), key.c_str(), defualtValue);
296 }
297  
298 bool Iniconfig::getBoolValue(const std::string & section, const std::string & key, const bool & defualtValue) {
299     if (false == _isloaded) { return false; }
300  
301     return  _ini.GetBoolValue(section.c_str(), key.c_str(), defualtValue);
302 }
303  
304 int Iniconfig::getSectionSize(const std::string & section) {
305     if (false == _isloaded) { return -1; }
306  
307     return _ini.GetSectionSize(section.c_str());
308 }
309  
310 void Iniconfig::printAll() {
311     CSimpleIniA::TNamesDepend sections;
312     // get all sections
313     _ini.GetAllSections(sections);
314     // 遍历所有 section 的 key 和 value
315     for (const auto &it : sections) {
316         const CSimpleIniA::TKeyVal *pKeyVal = _ini.GetSection(it.pItem);
317         if (nullptr != pKeyVal) {
318             for (const auto& it : *pKeyVal) {
319                 std::cout << it.first.pItem << " = " << it.second << std::endl;
320             }
321         }
322     }
323 }

测试代码:

 1 st_env_config config;
 2 Iniconfig cof(FILE_NAME, config);
 3  
 4  
 5 cof.addSection("abc");
 6 cof.addValue("abc", "name", "a");
 7 cof.addBoolValue("abc", "vip", true);
 8 cof.addDoubleValue("abc", "length", 175.5);
 9 cof.addLongValue("abc", "weight", 85);
10  
11 cof.setValue("abc", "name", "b");
12 cof.setBoolValue("abc", "vip", false);
13 cof.setDoubleValue("abc", "length", 188.8);
14 cof.setLongValue("abc", "weight", 90);
15  
16 //cof.deleteKey("abc", "name");
17 //cof.deleteKeys("abc", "vip");
18 //cof.deleteSection("abc");
19  
20 printf("name = %c\n", cof.getValueC("abc", "name"));
21 printf("name = %s\n", cof.getValue("abc", "name").c_str());
22 printf("bool = %d\n", cof.getBoolValue("abc", "vip"));
23 printf("lenght = %f\n", cof.getDoubleValue("abc", "length"));
24 printf("weight = %ld\n", cof.getLongValue("abc", "weight"));
25  
26 printf("%s\n", cof.getIniStr().c_str());
27 cof.saveFile(FILE_NAME);

五、总结
  simpleini库的基本用法如上面展示的那样,具体还有一些其他的api,现在还用不到,等用到了,再来补充!

  simpleini这个库应该也不算难,无非就是GetValue和SetValue的使用!

  ini文件常用来初始化程序,例如存储一些软件启动时初始化的一些基础数据,学习完这个库后,日后如果有写一些小软件就可以使用ini去初始化了!

posted on 2024-01-30 17:21  一杯清酒邀明月  阅读(1160)  评论(0编辑  收藏  举报