1、简介
- 支持解析ini文件
- 支持修改、保存ini文件
- 支持设置多个注释符,默认为“#”和’;’
- 运行在Linux 下
2、代码
inifile.h
#ifndef INIFILE_H_
#define INIFILE_H_
#include <vector>
#include <algorithm>
#include <string>
#include <string.h>
#include <iostream>
using std::string;
using std::vector;
//成功
#define RET_OK 0
// 没有找到匹配的]
#define ERR_UNMATCHED_BRACKETS 2
// 段为空
#define ERR_SECTION_EMPTY 3
// 段名已经存在
#define ERR_SECTION_ALREADY_EXISTS 4
// 解析key value失败
#define ERR_PARSE_KEY_VALUE_FAILED 5
// 打开文件失败
#define ERR_OPEN_FILE_FAILED 6
// 内存不足
#define ERR_NO_ENOUGH_MEMORY 7
// 没有找到对应的key
#define ERR_NOT_FOUND_KEY 8
// 没有找到对应的section
#define ERR_NOT_FOUND_SECTION 9
namespace inifile
{
//限定符号
const char delim[] = "\n";
//一条键值项
struct IniItem
{
string key;
string value;
string comment; // 每个键的注释,都是指该行上方的内容
string rightComment;
};
//一个节
struct IniSection
{
typedef vector<IniItem>::iterator IniItem_it; // 定义一个迭代器,即指向键元素的指针
IniItem_it begin()
{
return items.begin(); // 段结构体的begin元素指向items的头指针
}
IniItem_it end()
{
return items.end(); // 段结构体的end元素指向items的尾指针
}
string name;
string comment; // 每个段的注释,都是指该行上方的内容
string rightComment;
vector<IniItem> items; // 键值项数组,一个段可以有多个键值,所有用vector来储存
};
//Ini配置文件类
class IniFile
{
public:
IniFile();
~IniFile()
{
release();
}
public:
/* 打开并解析一个名为fname的INI文件 */
int Load(const string &fname);
/*xcl添加:传入一个路径返回一个数组*/
int Load(const string &filePath, vector<string> &retvalue);
/* 将内容保存到当前文件 */
int Save();
/* 将内容另存到一个名为fname的文件 */
int SaveAs(const string &fname);
/* 获取section段第一个键为key的string值,成功返回0,否则返回错误码 */
int GetStringValue(const string §ion, const string &key, string *value);
/* 获取section段第一个键为key的int值,成功返回0,否则返回错误码 */
int GetIntValue(const string §ion, const string &key, int *value);
/* 获取section段第一个键为key的double值,成功返回0,否则返回错误码 */
int GetDoubleValue(const string §ion, const string &key, double *value);
/* 获取section段第一个键为key的bool值,成功返回0,否则返回错误码 */
int GetBoolValue(const string §ion, const string &key, bool *value);
/* 获取上方注释,如果key=""则获取段注释 */
int GetComment(const string §ion, const string &key, string *comment);
/* 获取行尾注释,如果key=""则获取段的行尾注释 */
int GetRightComment(const string §ion, const string &key, string *rightComment);
/* 获取section段第一个键为key的string值,成功返回获取的值,否则返回默认值 */
void GetStringValueOrDefault(const string §ion, const string &key, string *value, const string &defaultValue);
/* 获取section段第一个键为key的int值,成功返回获取的值,否则返回默认值 */
void GetIntValueOrDefault(const string §ion, const string &key, int *value, int defaultValue);
/* 获取section段第一个键为key的double值,成功返回获取的值,否则返回默认值 */
void GetDoubleValueOrDefault(const string §ion, const string &key, double *value, double defaultValue);
/* 获取section段第一个键为key的bool值,成功返回获取的值,否则返回默认值 */
void GetBoolValueOrDefault(const string §ion, const string &key, bool *value, bool defaultValue);
/* 获取section段所有键为key的值,并将值赋到values的vector中 */
int GetValues(const string §ion, const string &key, vector<string> *values);
/* 获取section列表,并返回section个数 */
int GetSections(vector<string> *sections);
/* 获取section个数,至少存在一个空section */
int GetSectionNum();
/* 是否存在某个section */
bool HasSection(const string §ion);
/* 获取指定section的所有ken=value信息 */
IniSection *getSection(const string §ion = "");
/* 是否存在某个key */
bool HasKey(const string §ion, const string &key);
/* 设置字符串值 */
int SetStringValue(const string §ion, const string &key, const string &value);
/* 设置整形值 */
int SetIntValue(const string §ion, const string &key, int value);
/* 设置浮点数值 */
int SetDoubleValue(const string §ion, const string &key, double value);
/* 设置布尔值 */
int SetBoolValue(const string §ion, const string &key, bool value);
/* 设置注释,如果key=""则设置段注释 */
int SetComment(const string §ion, const string &key, const string &comment);
/* 设置行尾注释,如果key=""则设置段的行尾注释 */
int SetRightComment(const string §ion, const string &key, const string &rightComment);
/* 删除段 */
void DeleteSection(const string §ion);
/* 删除特定段的特定参数 */
void DeleteKey(const string §ion, const string &key);
/*设置注释分隔符,默认为"#" */
void SetCommentDelimiter(const string &delimiter);
const string &GetErrMsg();
public:
/* 获取section段所有键为key的值,并将值赋到values的vector中,,将注释赋到comments的vector中 */
int GetValues(const string §ion, const string &key, vector<string> *value, vector<string> *comments);
/* 同时设置值和注释 */
int setValue(const string §ion, const string &key, const string &value, const string &comment = "");
/* 去掉str前面的c字符 */
static void trimleft(string &str, char c = ' ');
/* 去掉str后面的c字符 */
static void trimright(string &str, char c = ' ');
/* 去掉str前面和后面的空格符,Tab符等空白符 */
static void trim(string &str);
/* 将字符串str按分割符delim分割成多个子串 */
public:
int UpdateSection(const string &cleanLine, const string &comment,
const string &rightComment, IniSection **section);
int AddKeyValuePair(const string &cleanLine, const string &comment,
const string &rightComment, IniSection *section);
void release();
bool split(const string &str, const string &sep, string *left, string *right);
bool IsCommentLine(const string &str);
bool parse(const string &content, string *key, string *value);
// for debug
void print();
public:
/* 获取section段第一个键为key的值,并将值赋到value中 */
int getValue(const string §ion, const string &key, string *value);
/* 获取section段第一个键为key的值,并将值赋到value中,将注释赋到comment中 */
int getValue(const string §ion, const string &key, string *value, string *comment);
bool StringCmpIgnoreCase(const string &str1, const string &str2);
bool StartWith(const string &str, const string &prefix);
public:
typedef vector<IniSection *>::iterator IniSection_it;
vector<IniSection *> sections_vt; // 用于存储段集合的vector容器
string iniFilePath;
string commentDelimiter;
string errMsg; // 保存出错时的错误信息
};
} // endof namespace inifile
#endif // INIFILE_H_
inifile.cpp
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <fstream>
#include "inifile.h"
using namespace std;
namespace inifile
{
// 构造函数,会初始化注释字符集合flags_(容器),目前只使用#和;作为注释前缀
IniFile::IniFile()
:commentDelimiter(";") //commentDelimiter("#")
{
}
//解析一行数据,得到键、值
/* --------------------------------------------------------------------------*/
/**
* @brief parse
*
* @param content 数据源指针
* @param key 键名
* @param value 键值
* @param c 分隔符
*
* @return bool
*/
/* ----------------------------------------------------------------------------*/
bool IniFile::parse(const string &content, string *key, string *value)
{
return split(content, "=", key, value);
}
int IniFile::UpdateSection(const string &cleanLine, const string &comment, const string &rightComment, IniSection **section)
{
IniSection *newSection;
// 查找右中括号
size_t index = cleanLine.find_first_of(']');
if (index == string::npos) {
errMsg = string("no matched ] found");
return ERR_UNMATCHED_BRACKETS;
}
int len = index - 1;
// 若段名为空,继续下一行
if (len <= 0) {
errMsg = string("section name is empty");
return ERR_SECTION_EMPTY;
}
// 取段名
string s(cleanLine, 1, len);
trim(s);
//检查段是否已存在
if (getSection(s) != NULL) {
errMsg = string("section ") + s + string("already exist");
return ERR_SECTION_ALREADY_EXISTS;
}
// 申请一个新段,由于map容器会自动排序,打乱原有顺序,因此改用vector存储(sections_vt)
newSection = new IniSection();
// 填充段名
newSection->name = s;
// 填充段开头的注释
newSection->comment = comment;
newSection->rightComment = rightComment;
sections_vt.push_back(newSection);
*section = newSection;
return 0;
}
int IniFile::AddKeyValuePair(const string &cleanLine, const string &comment, const string &rightComment, IniSection *section)
{
string key, value;
if (!parse(cleanLine, &key, &value)) {
errMsg = string("parse line failed:") + cleanLine;
return ERR_PARSE_KEY_VALUE_FAILED;
}
IniItem item;
item.key = key;
item.value = value;
item.comment = comment;
item.rightComment = rightComment;
section->items.push_back(item);
return 0;
}
int IniFile::Load(const string &filePath)
{
int err;
string line; // 带注释的行
string cleanLine; // 去掉注释后的行
string comment;
string rightComment;
IniSection *currSection = NULL; // 初始化一个字段指针
release();
iniFilePath = filePath;
std::ifstream ifs(iniFilePath);
if (!ifs.is_open()) {
errMsg = string("open") +iniFilePath+ string(" file failed");
return ERR_OPEN_FILE_FAILED;
}
//增加默认段,即 无名段""
currSection = new IniSection();
currSection->name = "";
sections_vt.push_back(currSection);
// 每次读取一行内容到line
while (std::getline(ifs, line)) {
trim(line);
// step 0,空行处理,如果长度为0,说明是空行,添加到comment,当作是注释的一部分
if (line.length() <= 0) {
comment += delim;
continue;
}
// step 1
// 如果行首不是注释,查找行尾是否存在注释
// 如果该行以注释开头,添加到comment,跳过当前循环,continue
if (IsCommentLine(line)) {
comment += line + delim;
continue;
}
// 如果行首不是注释,查找行尾是否存在注释,若存在,切割该行,将注释内容添加到rightComment
split(line, commentDelimiter, &cleanLine, &rightComment);
// step 2,判断line内容是否为段或键
//段开头查找 [
if (cleanLine[0] == '[') {
err = UpdateSection(cleanLine, comment, rightComment, &currSection);
} else {
// 如果该行是键值,添加到section段的items容器
err = AddKeyValuePair(cleanLine, comment, rightComment, currSection);
}
if (err != 0) {
ifs.close();
return err;
}
// comment清零
comment = "";
rightComment = "";
}
ifs.close();
return 0;
}
/*xcl添加: 传入一个路径返回一个数组*/
int IniFile::Load(const string &filePath, vector<string> &retvalue)
{
int err;
string line; // 带注释的行
string cleanLine; // 去掉注释后的行
string comment;
string rightComment;
IniSection *currSection = NULL; // 初始化一个字段指针
release();
iniFilePath = filePath;
std::ifstream ifs(iniFilePath);
if (!ifs.is_open())
{
errMsg = string("open") +iniFilePath+ string(" file failed");
return ERR_OPEN_FILE_FAILED;
}
//增加默认段,即 无名段""
currSection = new IniSection();
currSection->name = "";
sections_vt.push_back(currSection);
//每次读取一行内容到line
while (std::getline(ifs, line))
{
trim(line);//trim,整理一行字符串,去掉首尾空格
// step 0,空行处理,如果长度为0,说明是空行,添加到comment,当作是注释的一部分
if (line.length() <= 0)
{
comment += delim;
continue;
}
// step 1
// 如果行首不是注释,查找行尾是否存在注释
// 如果该行以注释开头,添加到comment,跳过当前循环,continue
if (IsCommentLine(line))
{
comment += line + delim;
continue;
}
// 如果行首不是注释,查找行尾是否存在注释,若存在,切割该行,将注释内容添加到rightComment
split(line, commentDelimiter, &cleanLine, &rightComment);
// step 2,判断line内容是否为段或键
//段开头查找 [
if (cleanLine[0] == '[')
{
err = UpdateSection(cleanLine, comment, rightComment, &currSection);
}
else
{
// 如果该行是键值,添加到section段的items容器
err = AddKeyValuePair(cleanLine, comment, rightComment, currSection);
}
if (err != 0)
{
ifs.close();
return err;
}
// comment清零
comment = "";
rightComment = "";
}
//把=右边的值放到一个数组里边
for(int i = 0; i < currSection->items.size(); i++)
{
retvalue.push_back(currSection->items[i].value);
}
ifs.close();
return 0;
}
int IniFile::Save()
{
return SaveAs(iniFilePath);
}
int IniFile::SaveAs(const string &filePath)
{
string data = "";
/* 载入section数据 */
for (IniSection_it sect = sections_vt.begin(); sect != sections_vt.end(); ++sect) {
if ((*sect)->comment != "") {
data += (*sect)->comment;
}
if ((*sect)->name != "") {
data += string("[") + (*sect)->name + string("]");
data += delim;
}
if ((*sect)->rightComment != "") {
data += " " + commentDelimiter +(*sect)->rightComment;
}
/* 载入item数据 */
for (IniSection::IniItem_it item = (*sect)->items.begin(); item != (*sect)->items.end(); ++item) {
if (item->comment != "") {
data += item->comment;
if (data[data.length()-1] != '\n') {
data += delim;
}
}
data += item->key + "=" + item->value;
if (item->rightComment != "") {
data += " " + commentDelimiter + item->rightComment;
}
if (data[data.length()-1] != '\n') {
data += delim;
}
}
}
cout<<data<<endl;
// std::ofstream ofs(filePath);
std::ofstream ofs;
ofs.open(filePath, ios::out|ios::trunc);
if(ofs.is_open()==false) //判断文件是否打开成功,is_open 返回值是一个bool类型
{
cout<<"文件打开失败!"<<endl;
}
ofs << data;
ofs.close();
cout<<"写文件结束";
return 0;
}
IniSection *IniFile::getSection(const string §ion /*=""*/)
{
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ++it) {
if ((*it)->name == section) {
return *it;
}
}
return NULL;
}
int IniFile::GetSections(vector<string> *sections)
{
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ++it) {
sections->push_back((*it)->name);
}
return sections->size();
}
int IniFile::GetSectionNum()
{
return sections_vt.size();
}
int IniFile::GetStringValue(const string §ion, const string &key, string *value)
{
return getValue(section, key, value);
}
int IniFile::GetIntValue(const string §ion, const string &key, int *intValue)
{
int err;
string strValue;
err = getValue(section, key, &strValue);
*intValue = atoi(strValue.c_str());
return err;
}
int IniFile::GetDoubleValue(const string §ion, const string &key, double *value)
{
int err;
string strValue;
err = getValue(section, key, &strValue);
*value = atof(strValue.c_str());
return err;
}
int IniFile::GetBoolValue(const string §ion, const string &key, bool *value)
{
int err;
string strValue;
err = getValue(section, key, &strValue);
if (StringCmpIgnoreCase(strValue, "true") || StringCmpIgnoreCase(strValue, "1")) {
*value = true;
} else if (StringCmpIgnoreCase(strValue, "false") || StringCmpIgnoreCase(strValue, "0")) {
*value = false;
}
return err;
}
/* 获取section段第一个键为key的string值,成功返回获取的值,否则返回默认值 */
void IniFile::GetStringValueOrDefault(const string §ion, const string &key,
string *value, const string &defaultValue)
{
if (GetStringValue(section, key, value) != 0) {
*value = defaultValue;
}
return;
}
/* 获取section段第一个键为key的int值,成功返回获取的值,否则返回默认值 */
void IniFile::GetIntValueOrDefault(const string §ion, const string &key, int *value, int defaultValue)
{
if (GetIntValue(section, key, value) != 0) {
*value = defaultValue;
}
return;
}
/* 获取section段第一个键为key的double值,成功返回获取的值,否则返回默认值 */
void IniFile::GetDoubleValueOrDefault(const string §ion, const string &key, double *value, double defaultValue)
{
if (GetDoubleValue(section, key, value) != 0) {
*value = defaultValue;
}
return;
}
/* 获取section段第一个键为key的bool值,成功返回获取的值,否则返回默认值 */
void IniFile::GetBoolValueOrDefault(const string §ion, const string &key, bool *value, bool defaultValue)
{
if (GetBoolValue(section, key, value) != 0) {
*value = defaultValue;
}
return;
}
/* 获取注释,如果key=""则获取段注释 */
int IniFile::GetComment(const string §ion, const string &key, string *comment)
{
IniSection *sect = getSection(section);
if (sect == NULL) {
errMsg = string("not find the section ")+section;
return ERR_NOT_FOUND_SECTION;
}
if (key == "") {
*comment = sect->comment;
return RET_OK;
}
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
*comment = it->comment;
return RET_OK;
}
}
errMsg = string("not find the key ")+section;
return ERR_NOT_FOUND_KEY;
}
/* 获取行尾注释,如果key=""则获取段的行尾注释 */
int IniFile::GetRightComment(const string §ion, const string &key, string *rightComment)
{
IniSection *sect = getSection(section);
if (sect == NULL) {
errMsg = string("not find the section ")+section;
return ERR_NOT_FOUND_SECTION;
}
if (key == "") {
*rightComment = sect->rightComment;
return RET_OK;
}
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
*rightComment = it->rightComment;
return RET_OK;
}
}
errMsg = string("not find the key ")+key;
return ERR_NOT_FOUND_KEY;
}
int IniFile::getValue(const string §ion, const string &key, string *value)
{
string comment;
return getValue(section, key, value, &comment);
}
int IniFile::getValue(const string §ion, const string &key, string *value, string *comment)
{
IniSection *sect = getSection(section);
if (sect == NULL) {
errMsg = string("not find the section ")+section;
return ERR_NOT_FOUND_SECTION;
}
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
*value = it->value;
*comment = it->comment;
return RET_OK;
}
}
errMsg = string("not find the key ")+key;
return ERR_NOT_FOUND_KEY;
}
int IniFile::GetValues(const string §ion, const string &key, vector<string> *values)
{
vector<string> comments;
return GetValues(section, key, values, &comments);
}
int IniFile::GetValues(const string §ion, const string &key, vector<string> *values, vector<string> *comments)
{
string value, comment;
values->clear();
comments->clear();
IniSection *sect = getSection(section);
if (sect == NULL) {
errMsg = string("not find the section ")+section;
return ERR_NOT_FOUND_SECTION;
}
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
value = it->value;
comment = it->comment;
values->push_back(value);
comments->push_back(comment);
}
}
if (values->size() == 0) {
errMsg = string("not find the key ")+key;
return ERR_NOT_FOUND_KEY;
}
return RET_OK;
}
bool IniFile::HasSection(const string §ion)
{
return (getSection(section) != NULL);
}
bool IniFile::HasKey(const string §ion, const string &key)
{
IniSection *sect = getSection(section);
if (sect != NULL) {
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
return true;
}
}
}
return false;
}
int IniFile::setValue(const string §ion, const string &key, const string &value, const string &comment /*=""*/)
{
IniSection *sect = getSection(section);
string comt = comment;
if (comt != "") {
comt = commentDelimiter + comt;
}
if (sect == NULL) {
//如果段不存在,新建一个
sect = new IniSection();
if (sect == NULL) {
errMsg = string("no enough memory!");
return ERR_NO_ENOUGH_MEMORY;
}
sect->name = section;
if (sect->name == "") {
// 确保空section在第一个
sections_vt.insert(sections_vt.begin(), sect);
} else {
sections_vt.push_back(sect);
}
}
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
it->value = value;
it->comment = comt;
return RET_OK;
}
}
// not found key
IniItem item;
item.key = key;
item.value = value;
item.comment = comt;
sect->items.push_back(item);
return RET_OK;
}
int IniFile::SetStringValue(const string §ion, const string &key, const string &value)
{
return setValue(section, key, value);
}
int IniFile::SetIntValue(const string §ion, const string &key, int value)
{
char buf[64] = {0};
snprintf(buf, sizeof(buf), "%d", value);
return setValue(section, key, buf);
}
int IniFile::SetDoubleValue(const string §ion, const string &key, double value)
{
char buf[64] = {0};
snprintf(buf, sizeof(buf), "%f", value);
return setValue(section, key, buf);
}
int IniFile::SetBoolValue(const string §ion, const string &key, bool value)
{
if (value) {
return setValue(section, key, "true");
} else {
return setValue(section, key, "false");
}
}
int IniFile::SetComment(const string §ion, const string &key, const string &comment)
{
IniSection *sect = getSection(section);
if (sect == NULL) {
errMsg = string("Not find the section ")+section;
return ERR_NOT_FOUND_SECTION;
}
if (key == "") {
sect->comment = comment;
return RET_OK;
}
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
it->comment = comment;
return RET_OK;
}
}
errMsg = string("not find the key ")+key;
return ERR_NOT_FOUND_KEY;
}
int IniFile::SetRightComment(const string §ion, const string &key, const string &rightComment)
{
IniSection *sect = getSection(section);
if (sect == NULL) {
errMsg = string("Not find the section ")+section;
return ERR_NOT_FOUND_SECTION;
}
if (key == "") {
sect->rightComment = rightComment;
return RET_OK;
}
for (IniSection::IniItem_it it = sect->begin(); it != sect->end(); ++it) {
if (it->key == key) {
it->rightComment = rightComment;
return RET_OK;
}
}
errMsg = string("not find the key ")+key;
return ERR_NOT_FOUND_KEY;
}
void IniFile::SetCommentDelimiter(const string &delimiter)
{
commentDelimiter = delimiter;
}
void IniFile::DeleteSection(const string §ion)
{
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ) {
if ((*it)->name == section) {
delete *it;
it = sections_vt.erase(it);
break;
} else {
it++;
}
}
}
void IniFile::DeleteKey(const string §ion, const string &key)
{
IniSection *sect = getSection(section);
if (sect != NULL) {
for (IniSection::IniItem_it it = sect->begin(); it != sect->end();) {
if (it->key == key) {
it = sect->items.erase(it);
break;
} else {
it++;
}
}
}
}
/*-------------------------------------------------------------------------*/
/**
@brief release: 释放全部资源,清空容器
@param none
@return none
*/
/*--------------------------------------------------------------------------*/
void IniFile::release()
{
iniFilePath = "";
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ++it) {
delete (*it); // 清除section
}
sections_vt.clear();
}
/*-------------------------------------------------------------------------*/
/**
@brief 判断是否是注释
@param str 一个string变量
@return 如果是注释则为真
*/
/*--------------------------------------------------------------------------*/
bool IniFile::IsCommentLine(const string &str)
{
return StartWith(str, commentDelimiter);
}
/*-------------------------------------------------------------------------*/
/**
@brief print for debug
@param none
@return none
*/
/*--------------------------------------------------------------------------*/
void IniFile::print()
{
printf("############ print start ############\n");
printf("filePath:[%s]\n", iniFilePath.c_str());
printf("commentDelimiter:[%s]\n", commentDelimiter.c_str());
for (IniSection_it it = sections_vt.begin(); it != sections_vt.end(); ++it) {
printf("comment :[\n%s]\n", (*it)->comment.c_str());
printf("section :\n[%s]\n", (*it)->name.c_str());
if ((*it)->rightComment != "") {
printf("rightComment:\n%s", (*it)->rightComment.c_str());
}
for (IniSection::IniItem_it i = (*it)->items.begin(); i != (*it)->items.end(); ++i) {
printf(" comment :[\n%s]\n", i->comment.c_str());
printf(" parm :%s=%s\n", i->key.c_str(), i->value.c_str());
if (i->rightComment != "") {
printf(" rcomment:[\n%s]\n", i->rightComment.c_str());
}
}
}
printf("############ print end ############\n");
return;
}
const string & IniFile::GetErrMsg()
{
return errMsg;
}
bool IniFile::StartWith(const string &str, const string &prefix)
{
if (strncmp(str.c_str(), prefix.c_str(), prefix.size()) == 0) {
return true;
}
return false;
}
void IniFile::trimleft(string &str, char c /*=' '*/)
{
int len = str.length();
int i = 0;
while (str[i] == c && str[i] != '\0') {
i++;
}
if (i != 0) {
str = string(str, i, len - i);
}
}
void IniFile::trimright(string &str, char c /*=' '*/)
{
int i = 0;
int len = str.length();
for (i = len - 1; i >= 0; --i) {
if (str[i] != c) {
break;
}
}
str = string(str, 0, i + 1);
}
/*-------------------------------------------------------------------------*/
/**
@brief trim,整理一行字符串,去掉首尾空格
@param str string变量
*/
/*--------------------------------------------------------------------------*/
void IniFile::trim(string &str)
{
int len = str.length();
int i = 0;
while ((i < len) && isspace(str[i]) && (str[i] != '\0')) {
i++;
}
if (i != 0) {
str = string(str, i, len - i);
}
len = str.length();
for (i = len - 1; i >= 0; --i) {
if (!isspace(str[i])) {
break;
}
}
str = string(str, 0, i + 1);
}
/*-------------------------------------------------------------------------*/
/**
@brief split,用分隔符切割字符串
@param str 输入字符串
@param left_str 分隔后得到的左字符串
@param right_str 分隔后得到的右字符串(不包含seperator)
@param seperator 分隔符
@return pos
*/
/*--------------------------------------------------------------------------*/
bool IniFile::split(const string &str, const string &sep, string *pleft, string *pright)
{
size_t pos = str.find(sep);
string left, right;
if (pos != string::npos) {
left = string(str, 0, pos);
right = string(str, pos+1);
trim(left);
trim(right);
*pleft = left;
*pright = right;
return true;
} else {
left = str;
right = "";
trim(left);
*pleft = left;
*pright = right;
return false;
}
}
bool IniFile::StringCmpIgnoreCase(const string &str1, const string &str2)
{
string a = str1;
string b = str2;
transform(a.begin(), a.end(), a.begin(), towupper);
transform(b.begin(), b.end(), b.begin(), towupper);
return (a == b);
}
} /* namespace inifile */
makefile
ifeq ($(DEBUG),Enable)
CPPFLAGS = -D_DEBUG -g -Wall
else
CPPFLAGS = -s
endif
INCS=-I./
LIBS=./lib
OUTDIR=./
TARGET=ini_test
exe:
g++ -std=gnu++11 $(CPPFLAGS) $(INCS) ./*.cpp -o $(OUTDIR)/$(TARGET)
all: exe
clean:
rm $(OUTDIR)/$(TARGET)