最近在学习时,发现自己还不会操作ini文件,想着以前工作时接触到的项目或多或少都要用到ini文件去保存初始化程序的数据;所以赶紧去网上搜索以下C/C++操作ini文件都有些什么库可以玩玩;搜索到有:
1. inih:这是C语言小巧的库,更适合嵌入式开发;
2. iniparser:这是C语言的库,挺方便使用的,开源,两个.h文件和两个.c文件,但只能在Linux中使用;
3. simpleini:这是C++的库,挺方便使用的,跨平台,开源,就两个.h文件和一个.c文件,且支持中文;
所以最后我选择了simpleini这个库去学习使用!
目录
一、介绍
1. ini介绍
2. simpleini介绍
二、下载
三、使用
1. 加载ini文件
2. 简单配置
3. 增
1). 添加一个新的节点(section)
2). 添加一个新的 key和value
4. 改
1). 修改值(value)
5. 删
1). 删除 key 和 value
2). 当最后一个key也被删除掉后,section1也会被删除
3). 删除整个节点(section)和其下的所有键(key)
6. 查
1). 将下图中的ini文件内容读取打印显示
2). 遍历ini文件的所有内容
3). 遍历所有节点(section)
4). 遍历指定节点的键(key)
5). 获取一个键对应多个值
6). 获取指定节点(section)里有多少键值
7. 保存
1). 保存到文件
2). 保存到C++字符串
8. 中文乱码问题
四、封装
configdef.h
iniconfig.h
iniconfig.cpp
测试代码:
五、总结
ini文件由 [section] 节点 和 key 键 和 value 值 构成。
例如一个简单的ini文件如下所示:
[message]
name = 张三
age = 25
height = 173.2
; 这是一个注释
[server]
ip = 127.0.0.1
port = 6666
message就是节点,节点下方就是它的键和值;server也是一个节点。
如果需要注释,使用英文分号 ' ; ' 即可。
一个跨平台库,提供了一个简单的API来读取和写入ini风格的配置文件。它支持ASCII、MBCS和Unicode格式的数据文件。它被明确设计为可移植到任何平台,并已在Windows, WinCE和Linux上进行了测试。使用MIT许可证作为开源和免费发布.
功能概述
GitHub链接:GitHub - brofield/simpleini: Cross-platform C++ library providing a simple API to read and write INI-style configuration fileshttps://github.com/brofield/simpleini
gitte链接:
simpleini: SimpleIni 是一个跨平台的 C++ 库,提供一个简单的 API 用于操作 ini 配置文件 (gitee.com)https://gitee.com/mirrors/simpleini
下载后解压
这三个文件可在 Window 或 Linux 环境去使用!
以下介绍的用法,Linux和Window环境均可使用!
包含头文件:
#include "SimpleIni.h"
#define FILE_NAME "./test1.ini"
test1.ini内容如下:
// 定义ini文档对象
CSimpleIniA ini;
// 加载ini文件
SI_Error rc;
rc = ini.LoadFile(FILE_NAME); // 另一种方式:SI_Error LoadFile(FILE * a_fpFile);
if (rc < 0) {
printf("加载 %s ini 文件失败!\n", FILE_NAME);
return -1;
}
rc返回值有以下这些:
using SI_Error = int;
constexpr int SI_OK = 0; //!< No error
constexpr int SI_UPDATED = 1; //!< An existing value was updated
constexpr int SI_INSERTED = 2; //!< A new value was inserted
// note: test for any error with (retval < 0)
constexpr int SI_FAIL = -1; //!< Generic failure
constexpr int SI_NOMEM = -2; //!< Out of memory error
constexpr int SI_FILE = -3; //!< File error (see errno for detail error)
// 设置INI数据的存储格式,参数为true时保存为UTF-8格式,否则为本地编码格式
ini.SetUnicode(true);
// 是否允许一个关键字对应多个值,默认为允许;若不允许,则将最后一个值作为此关键字关联的值
ini.SetMultiKey(false);
SetValue
参数一:节点
参数二:键
参数三:值
返回值:SI_Error (也就是int类型)
// 添加一个新的 section
rc = ini.SetValue("section1", nullptr, nullptr);
if (rc < 0) {
printf("添加section1失败!\n");
return -1;
}
// 添加一个新的 key和value
rc = ini.SetValue("section1", "name", "张三");
if (rc < 0) {
printf("添加name失败!\n");
return -1;
}
//const char *name = ini.GetValue("section1", "name", "");
//printf("name = %s\n", name);
ini.SetValue("section1", "age", "24");
ini.SetValue("section1", "sex", "男");
注意:如果name存在,则会将name键(key)对应的值(value)修改为张三;
还可以使用SetLongValue、SetDoubleValue、SetBoolValue去添加:
ini.SetLongValue("server", "length", 173);
ini.SetDoubleValue("server", "weight", 53.5);
ini.SetBoolValue("server", "vip", true);
SetValue
参数一:节点
参数二:键
参数三:值
返回值:SI_Error (也就是int类型)
// 修改value,如果键(name)不存在则添加该 key和value
rc = ini.SetValue("section1", "name", "李四");
if (rc < 0) {
printf("修改name失败!\n");
return -1;
}
//const char *name = ini.GetValue("section1", "name");
//printf("name = %s\n", name);
注意:如果要修改的值对应的键不存在,则会添加改键和值到section1节点中!
貌似无法修改节点(section) 和 键(key),我没有找到相关的api。。。
还可以使用SetLongValue、SetDoubleValue、SetBoolValue去添加:
ini.SetLongValue("server", "length", 1000);
ini.SetDoubleValue("server", "weight", 66.66);
ini.SetBoolValue("server", "vip", false);
Delete
参数一:节点
参数二:键
返回值:bool
bool done = false;
// 删除 key
done = ini.Delete("section1", "name");
if (false == done) {
printf("删除 section1 - name 失败!\n");
return -1;
}
// 如果最后一个key也被删除了,那么section也会被一起删除掉
bool deleteSectionIfEmpty = true;
done = ini.Delete("section1", "age", deleteSectionIfEmpty);
if (false == done) {
printf("删除 section1 - age 失败!\n");
return -1;
}
此时section1中还由两个key,随意上面的代码执行后只会将age给删除掉,并不会也把section1删掉;
如果将Delete的第三个参数值true去删除sex,那么section1也会一并删掉!
ini.Delete("section1", "sex", true);
将section1还原到一开始的的样子 ,方便下面第3点操作删除
// 删除整个section和其中的所有键
done = ini.Delete("section1", nullptr);
if (false == done) {
printf("删除整个section和其中的所有键 失败 !\n");
return -1;
}
执行如上代码,就会将刚刚还原的section1都给删除掉!
GetValue
参数一:节点
参数二:键
参数三:如果没找到,返回参数三指定的默认值
返回值:const char *
int _int = std::stoi(ini.GetValue("section", "_int", "-1"));
printf("_int = %d\n", _int);
long long _long = std::stoll(ini.GetValue("section", "_long", "-1"));
printf("_long = %lld\n", _long);
double _double = std::stod(ini.GetValue("section", "_double", "0.0"));
printf("_double = %lf\n", _double);
float _float = std::stof(ini.GetValue("section", "_float", "0.0"));
printf("_float = %f\n", _float);
bool _bool = ini.GetBoolValue("section", "_bool", false);
printf("_bool = %s\n", _bool ? "true" : "false");
std::string _string = ini.GetValue("section", "_string", "");
printf("_string = %s\n", _string.c_str());
std::string _string2 = ini.GetValue("section", "_string2", "");
printf("_string2 = %s\n", _string2.c_str());
char _char = ini.GetValue("section", "_char", "")[0];
printf("_char = %c\n", _char);
std::string ip = ini.GetValue("server", "ip", "0.0.0.0");
printf("ip = %s\n", ip.c_str());
int port = std::stoi(ini.GetValue("server", "port", "-1"));
printf("port = %d\n", port);
std::string name1 = ini.GetValue("server", "name", "");
printf("name = %s\n", name1.c_str());
还可以使用GetLongValue、GetDoubleValue、GetBoolValue去查:
int lenght = ini.GetLongValue("server", "length", -1);
double weight = ini.GetDoubleValue("server", "weight", -1);
bool vip = ini.GetBoolValue("server", "vip", false);
GetAllSections:获取所有节点,参数一引用返回list链表;
GetSection:根据参数字符串,获取节点,返回multimap容器;
CSimpleIniA::TNamesDepend sections;
// get all sections
ini.GetAllSections(sections);
// 遍历所有 section 的 key 和 value
for (const auto &it : sections) {
const CSimpleIniA::TKeyVal *pKeyVal = ini.GetSection(it.pItem);
if (nullptr != pKeyVal) {
for (const auto& it : *pKeyVal) {
std::cout << it.first.pItem << " = " << it.second << std::endl;
}
}
}
CSimpleIniA::TNamesDepend sections1;
// 获取所有section
ini.GetAllSections(sections1);
// 遍历所有 sections
for (const auto &it : sections1) {
std::cout << it.pItem << std::endl;
}
GetAllKeys:获取所有键,参数二引用返回list链表;
CSimpleIniA::TNamesDepend keys;
// get all keys in a section
ini.GetAllKeys("section", keys);
// 遍历 section 指定的所有 key
for (const auto &it : keys) {
std::cout << it.pItem << std::endl;
}
首先,ini.SetMultiKey(true);得设置为true,否则只会获取到最后一个值,其他会被删除掉;
在ini文件中的server节点添加多几个name键
使用以下代码获取:
CSimpleIniA::TNamesDepend values;
// 获取 key 所对应的多个 value;ini.SetMultiKey(true);一定要设置为true,
// 否则就只会获取到最后一个,其他删除
ini.GetAllValues("server", "name", values);
// 遍历一个 key 对应多个 value;
for (const auto &it : values) {
printf("name = %s\n", it.pItem);
}
// 获取section里有多少值
int size = ini.GetSectionSize("section");
printf("section 的 key 个数:%d\n", size);
注意:以上增、删、改,只有执行保存代码后,才会在文件做出相应的修改!
/* 保存到文件中 */
rc = ini.SaveFile(FILE_NAME);
if (rc < 0) {
printf("保存 %s ini文件失败\n", FILE_NAME);
}
std::string strIni = "";
ini.Save(strIni);
printf("%s\n", strIni.c_str());
window环境写入或者读取中文有乱码现象,将文件编码改成ANSI编码即可!
可以使用notepad++去修改,如下图:
Linux环境出现中文乱码问题,那就新建一个文件,然后再手动敲上需要的信息即可,例如
touch test1.ini 或 vim test1.ini
记得,千万别从从Window拷贝进Linux中,文件中是不会显示出乱码,但是读取写入时会有乱码!
我遇到的乱码问题,通过上面的方法就可以解决了!
可以根据自己项目的具体需求去封装成方便调用的接口去使用!
例如我下面的用法:
这个是定义结构体的头文件,从ini文件中读取的数据都存放在结构体中!
#ifndef _COMMON_CONFIGDEF_H_
#define _COMMON_CONFIGDEF_H_
#include
typedef struct st_env_config {
// 对应ini文件
// section
int _int;
long _long;
double _double;
float _float;
bool _bool;
std::string _string;
char _char;
// server
std::string _ip;
unsigned short _port;
// 构造函数
st_env_config() { }
st_env_config(int _int, long _long, double _double, float _float, bool _bool, std::string _string, char _char, std::string _ip, unsigned short _port) {
this->_int = _int;
this->_long = _long;
this->_double = _double;
this->_float = _float;
this->_bool = _bool;
this->_string = _string;
this->_char = _char;
this->_ip = _ip;
this->_port = _port;
}
// 赋值运算符重载
st_env_config &operator=(const st_env_config &config) {
if (this != &config) {
this->_int = config._int;
this->_long = config._long;
this->_double = config._double;
this->_float = config._float;
this->_bool = config._bool;
this->_string = config._string;
this->_char = config._char;
this->_ip = _ip;
this->_port = _port;
}
return *this;
}
}_st_env_config;
#endif // _COMMON_CONFIGDEF_H_
这个是封装simpleini的头文件
#ifndef _COMMON_INICONFIG_H_
#define _COMMON_INICONFIG_H_
#include
#include "configdef.h"
#include "../simpleini/SimpleIni.h"
class Iniconfig {
public:
Iniconfig();
Iniconfig(const std::string &path, st_env_config &config);
~Iniconfig();
// 加载ini文件
bool loadfile(const std::string &path);
// 保存ini文件
bool saveFile(const std::string &fileName);
// 设置INI数据的存储格式,参数为true时保存为UTF-8格式,否则为本地编码格式
void setUnicode(const bool utf8 = true);
// 是否允许一个关键字对应多个值,默认为允许;若不允许,则将最后一个值作为此关键字关联的值,其他删除
void setMultiKey(const bool multKey = false);
// 获取ini文件中的数据,保存到结构体中
bool getData(st_env_config &config);
// 获取ini文件字符串
std::string getIniStr();
// 添加一个新的section
bool addSection(const std::string §ion);
// 添加一个新的key和value,value可以默认为空
bool addValue(const std::string §ion, const std::string &key, const std::string &value = "");
bool addLongValue(const std::string §ion, const std::string &key, const long value = 0);
bool addDoubleValue(const std::string §ion, const std::string &key, const double value = 0.0);
bool addBoolValue(const std::string §ion, const std::string &key, const bool value = false);
// 修改value,如果key不存在,则会创建key和value
bool setValue(const std::string §ion, const std::string &key, const std::string &value);
bool setLongValue(const std::string §ion, const std::string &key, const long value = 0);
bool setDoubleValue(const std::string §ion, const std::string &key, const double value = 0.0);
bool setBoolValue(const std::string §ion, const std::string &key, const bool value = false);
// 删除key
bool deleteKey(const std::string §ion, const std::string &key);
// 删除key,如果最后一个key也被删除了,那么section也会被一起删除掉
bool deleteKeys(const std::string §ion, const std::string &key, const bool deleteSectionIfEmpty = true);
// 删除section,整个section和其中的所有键值
bool deleteSection(const std::string §ion);
// 获取string类型值
std::string getValue(const std::string §ion, const std::string &key, const std::string &defualtValue = "");
// 获取char类型值
char getValueC(const std::string §ion, const std::string &key, const char &defualtValue = '\0');
// 获取long、int、short类型
long getLongValue(const std::string §ion, const std::string &key, const short &defualtValue = -1);
// 获取double、float类型
double getDoubleValue(const std::string §ion, const std::string &key, const double &defualtValue = 0.0);
// 获取bool类型
bool getBoolValue(const std::string §ion, const std::string &key, const bool &defualtValue = false);
// 获取section里有多少值
int getSectionSize(const std::string §ion);
// 遍历所有
void printAll();
private:
bool _isloaded; // 是否已经加载
CSimpleIniA _ini; // ini操作对象
};
#endif // _COMMON_INICONFIG_H_
这个是封装simpleini的cpp文件内容
#include "iniconfig.h"
#include
#include
Iniconfig::Iniconfig() : _isloaded(false) {
_ini.SetUnicode(true); // 使用utf8编码
_ini.SetMultiKey(false); // 不允许一个key对应多个value
_isloaded = false;
}
Iniconfig::Iniconfig(const std::string & path, st_env_config &config) {
_ini.SetUnicode(true); // 使用utf8编码
_ini.SetMultiKey(false); // 不允许一个key对应多个value
_isloaded = false;
SI_Error rc;
rc = _ini.LoadFile(path.c_str()); // 另一种方式:SI_Error LoadFile(FILE * a_fpFile);
if (rc < 0) {
printf("加载 %s ini 文件失败!\n", path.c_str());
_isloaded = false;
return;
}
int _int = getLongValue("section", "_int", -1);
long _long = getLongValue("section", "_long", -1);
double _double = getDoubleValue("section", "_double", 0.0);
float _float = getDoubleValue("section", "_float", 0.0);
bool _bool = getBoolValue("section", "_bool", false);
std::string _string = getValue("section", "_string", "");
char _char = getValueC("section", "_char", '\0');
std::string ip = getValue("server", "ip", "0.0.0.0");
unsigned short port = getLongValue("section", "port", -1);
config = st_env_config(_int, _long, _double, _float, _bool, _string, _char, ip, port);
_isloaded = true;
}
Iniconfig::~Iniconfig() {
}
// 加载ini文件
bool Iniconfig::loadfile(const std::string &path) {
if (false == _isloaded) {
SI_Error rc;
rc = _ini.LoadFile(path.c_str()); // 另一种方式:SI_Error LoadFile(FILE * a_fpFile);
if (rc < 0) {
printf("加载 %s ini 文件失败!\n", path.c_str());
_isloaded = false;
return _isloaded;
}
_isloaded = true;
}
return _isloaded;
}
bool Iniconfig::saveFile(const std::string & fileName) {
SI_Error rc = _ini.SaveFile(fileName.c_str());
if (rc < 0) {
printf("保存 %s ini文件失败\n", fileName.c_str());
return false;
}
_isloaded = false;
return true;
}
void Iniconfig::setUnicode(const bool utf8) {
_ini.SetUnicode(utf8); // true:使用utf8编码
}
void Iniconfig::setMultiKey(const bool multKey) {
_ini.SetMultiKey(multKey); // false:不允许一个key对应多个value
}
bool Iniconfig::getData(st_env_config & config) {
if (true == _isloaded) {
int _int = getLongValue("section", "_int", -1);
long _long = getLongValue("section", "_long", -1);
double _double = getDoubleValue("section", "_double", 0.0);
float _float = getDoubleValue("section", "_float", 0.0);
bool _bool = getBoolValue("section", "_bool", false);
std::string _string = getValue("section", "_string", "");
char _char = getValueC("section", "_char", '\0');
std::string ip = getValue("server", "ip", "0.0.0.0");
unsigned short port = getLongValue("section", "port", -1);
config = st_env_config(_int, _long, _double, _float, _bool, _string, _char, ip, port);
return true;
}
return false;
}
std::string Iniconfig::getIniStr() {
std::string str = "";
if (true == _isloaded) {
SI_Error rc = _ini.Save(str);
if (rc < 0) {
printf("获取ini文件字符串失败!\n");
str = "";
}
}
return str;
}
bool Iniconfig::addSection(const std::string & section) {
if (false == _isloaded) { return false; }
SI_Error rc = _ini.SetValue(section.c_str(), nullptr, nullptr);
if (rc < 0) {
printf("添加 %s 节点失败!\n", section.c_str());
return false;
}
return true;
}
bool Iniconfig::addValue(const std::string & section, const std::string & key, const std::string & value) {
if (false == _isloaded) { return false; }
SI_Error rc = _ini.SetValue(section.c_str(), key.c_str(), value.c_str());
if (rc < 0) {
printf("添加 %s key失败!\n", key.c_str());
return false;
}
return true;
}
bool Iniconfig::addLongValue(const std::string & section, const std::string & key, const long value) {
if (false == _isloaded) { return false; }
SI_Error rc = _ini.SetLongValue(section.c_str(), key.c_str(), value);
if (rc < 0) {
printf("添加 %s key失败!\n", key.c_str());
return false;
}
return true;
}
bool Iniconfig::addDoubleValue(const std::string & section, const std::string & key, const double value) {
if (false == _isloaded) { return false; }
SI_Error rc = _ini.SetDoubleValue(section.c_str(), key.c_str(), value);
if (rc < 0) {
printf("添加 %s key失败!\n", key.c_str());
return false;
}
return true;
}
bool Iniconfig::addBoolValue(const std::string & section, const std::string & key, const bool value) {
if (false == _isloaded) { return false; }
SI_Error rc = _ini.SetBoolValue(section.c_str(), key.c_str(), value);
if (rc < 0) {
printf("添加 %s key失败!\n", key.c_str());
return false;
}
return true;
}
bool Iniconfig::setValue(const std::string & section, const std::string & key, const std::string & value) {
if (false == _isloaded) { return false; }
SI_Error rc = _ini.SetValue(section.c_str(), key.c_str(), value.c_str());
if (rc < 0) {
printf("修改 %s value失败!\n", value.c_str());
return false;
}
return true;
}
bool Iniconfig::setLongValue(const std::string & section, const std::string & key, const long value) {
if (false == _isloaded) { return false; }
SI_Error rc = _ini.SetLongValue(section.c_str(), key.c_str(), value);
if (rc < 0) {
printf("修改 %s key失败!\n", key.c_str());
return false;
}
return true;
}
bool Iniconfig::setDoubleValue(const std::string & section, const std::string & key, const double value) {
if (false == _isloaded) { return false; }
SI_Error rc = _ini.SetDoubleValue(section.c_str(), key.c_str(), value);
if (rc < 0) {
printf("修改 %s key失败!\n", key.c_str());
return false;
}
return true;
}
bool Iniconfig::setBoolValue(const std::string & section, const std::string & key, const bool value) {
if (false == _isloaded) { return false; }
SI_Error rc = _ini.SetBoolValue(section.c_str(), key.c_str(), value);
if (rc < 0) {
printf("修改 %s key失败!\n", key.c_str());
return false;
}
return true;
}
bool Iniconfig::deleteKey(const std::string & section, const std::string & key) {
if (false == _isloaded) { return false; }
bool done = false;
// 删除 key
done = _ini.Delete(section.c_str(), key.c_str());
if (false == done) {
printf("删除 %s - %s 失败!\n", section.c_str(), key.c_str());
return false;
}
return true;
}
bool Iniconfig::deleteKeys(const std::string & section, const std::string & key, const bool deleteSectionIfEmpty) {
if (false == _isloaded) { return false; }
bool done = false;
done = _ini.Delete(section.c_str(), key.c_str(), deleteSectionIfEmpty);
if (false == done) {
printf("删除 %s - %s 失败!\n", section.c_str(), key.c_str());
return false;
}
return true;
}
bool Iniconfig::deleteSection(const std::string & section) {
if (false == _isloaded) { return false; }
bool done = false;
done = _ini.Delete(section.c_str(), nullptr);
if (false == done) {
printf("删除整个 %s 和其下的所有 键 失败 !\n", section.c_str());
return false;
}
return true;
}
std::string Iniconfig::getValue(const std::string & section, const std::string & key, const std::string & defualtValue) {
if (false == _isloaded) { return ""; }
return _ini.GetValue(section.c_str(), key.c_str(), defualtValue.c_str());
}
char Iniconfig::getValueC(const std::string & section, const std::string & key, const char & defualtValue) {
if (false == _isloaded) { return '\0'; }
std::string str = std::to_string(defualtValue);
return _ini.GetValue(section.c_str(), key.c_str(), str.c_str())[0];
}
long Iniconfig::getLongValue(const std::string & section, const std::string & key, const short & defualtValue) {
if (false == _isloaded) { return -1; }
return _ini.GetLongValue(section.c_str(), key.c_str(), defualtValue);
}
double Iniconfig::getDoubleValue(const std::string & section, const std::string & key, const double & defualtValue) {
if (false == _isloaded) { return -1.0; }
return _ini.GetDoubleValue(section.c_str(), key.c_str(), defualtValue);
}
bool Iniconfig::getBoolValue(const std::string & section, const std::string & key, const bool & defualtValue) {
if (false == _isloaded) { return false; }
return _ini.GetBoolValue(section.c_str(), key.c_str(), defualtValue);
}
int Iniconfig::getSectionSize(const std::string & section) {
if (false == _isloaded) { return -1; }
return _ini.GetSectionSize(section.c_str());
}
void Iniconfig::printAll() {
CSimpleIniA::TNamesDepend sections;
// get all sections
_ini.GetAllSections(sections);
// 遍历所有 section 的 key 和 value
for (const auto &it : sections) {
const CSimpleIniA::TKeyVal *pKeyVal = _ini.GetSection(it.pItem);
if (nullptr != pKeyVal) {
for (const auto& it : *pKeyVal) {
std::cout << it.first.pItem << " = " << it.second << std::endl;
}
}
}
}
st_env_config config;
Iniconfig cof(FILE_NAME, config);
cof.addSection("abc");
cof.addValue("abc", "name", "a");
cof.addBoolValue("abc", "vip", true);
cof.addDoubleValue("abc", "length", 175.5);
cof.addLongValue("abc", "weight", 85);
cof.setValue("abc", "name", "b");
cof.setBoolValue("abc", "vip", false);
cof.setDoubleValue("abc", "length", 188.8);
cof.setLongValue("abc", "weight", 90);
//cof.deleteKey("abc", "name");
//cof.deleteKeys("abc", "vip");
//cof.deleteSection("abc");
printf("name = %c\n", cof.getValueC("abc", "name"));
printf("name = %s\n", cof.getValue("abc", "name").c_str());
printf("bool = %d\n", cof.getBoolValue("abc", "vip"));
printf("lenght = %f\n", cof.getDoubleValue("abc", "length"));
printf("weight = %ld\n", cof.getLongValue("abc", "weight"));
printf("%s\n", cof.getIniStr().c_str());
cof.saveFile(FILE_NAME);
simpleini库的基本用法如上面展示的那样,具体还有一些其他的api,现在还用不到,等用到了,再来补充!
simpleini这个库应该也不算难,无非就是GetValue和SetValue的使用!
ini文件常用来初始化程序,例如存储一些软件启动时初始化的一些基础数据,学习完这个库后,日后如果有写一些小软件就可以使用ini去初始化了!