参考来源:https://blog.csdn.net/m_buddy/article/details/54097131
目录
Ini文件格式
源码
测试源码
测试结果
//IniFile.h
#ifndef INIFILE_H_
#define INIFILE_H_
#include "stdafx.h"
#include
#include
#include
#include
#include
//IniFile.cpp
#include "stdafx.h"
#include
#include "IniFile.h"
CSection::CSection(const string& section, const string& key, const string& value)
{
this->m_section = section;
this->m_key = key;
this->m_value = value;
}
void CKeyValue::AddKeyValue(const string& key, const string& value)
{
m_keyValue.insert(std::pair(key, value));
}
CIniFile::CIniFile()
{
}
CIniFile::~CIniFile()
{
m_secKeyValue.clear();
}
//去除字符串str左右空格
string& CIniFile::Trim(string& str)
{
str.erase(0, str.find_first_not_of(" \t\n\r"));
str.erase(str.find_last_not_of(" \t\n\r") + 1);
return str;
}
/*
加载ini文件filename
思路:
1、按 class {section、key、value } 数据结构读取ini中所有节点、键值内容
2、利用map的insert属性,去重复得到所有section
3、重组读取的ini内容为下面结构
section1
key1 value1
key2 value2
section2
key3 value3
key4 value4
*/
bool CIniFile::LoadFromIni(const string& filename)
{
ifstream outFile(filename.c_str());
if (!outFile.is_open())
return false;
string strSection = "", strKey="", strValue="", strLine = "";
vector vecSection;
string::size_type posLeft = string::npos;
string::size_type posRight = string::npos;
string::size_type posKeyValue = string::npos;
while (!outFile.eof())
{
getline(outFile, strLine);
//空行
if (0 == strLine.length())
continue;
//ini注释,以#开头
if (0==strLine.find("#"))
continue;
//读section节点
posLeft = strLine.find("[");
posRight = strLine.find("]");
if (string::npos != posLeft && string::npos != posRight)
{
strSection = strLine.substr(posLeft + strlen("["), posRight - posLeft - strlen("["));
strKey = "";
strValue = "";
}
//读key、value
posKeyValue = strLine.find("=");
if (string::npos != posKeyValue)
{
strKey = strLine.substr(0, posKeyValue);
strValue = strLine.substr(posKeyValue + strlen("="), strLine.length() - posKeyValue - strlen("="));
}
if (strSection.length()>0 && strKey.length()>0 && strValue.length()>0)
{
CSection sec(strSection, strKey, strValue);
vecSection.push_back(sec);
}
}
outFile.close();
outFile.clear();//清空缓冲
//利用map的insert属性,去重复拿出所有节点
map temp;
for (vector::iterator it = vecSection.begin(); it != vecSection.end(); it++)
{
temp.insert(std::pair(it->m_section, ""));
}
/*
重组ini结构
section1
key1 value1
key2 value2
section2
key3 value3
key4 value4
*/
for (map::iterator sectionItor = temp.begin(); sectionItor != temp.end(); sectionItor++)
{
CKeyValue keyValue;
for (vector::iterator vecItor = vecSection.begin(); vecItor != vecSection.end(); vecItor++)
{
if (vecItor->m_section == sectionItor->first)
{
keyValue.AddKeyValue(vecItor->m_key, vecItor->m_value);
}
}
m_secKeyValue.insert(std::pair(sectionItor->first, keyValue));
}
return true;
}
string CIniFile::GetValue(const string& section, const string& key)
{
map::iterator secKeyValueItor = m_secKeyValue.find(section);
map::iterator keyValue = secKeyValueItor->second.m_keyValue.find(key);
if (keyValue==secKeyValueItor->second.m_keyValue.end() || keyValue->second.empty())
return "";
else
return keyValue->second;
}
vector::size_type CIniFile::SetValue(const string& section, const string& key, const string& value)
{
map::iterator secKeyValue = m_secKeyValue.find(section);
if (m_secKeyValue.end() != secKeyValue)
secKeyValue->second.m_keyValue[key] = value;
else
{
CKeyValue keyValue;
keyValue.AddKeyValue(key, value);
m_secKeyValue.insert(std::pair(section, keyValue));
}
return m_secKeyValue.size();
}
bool CIniFile::SaveToIni(const string& path)
{
ofstream inFile(path.c_str());
if (!inFile.is_open())
return false;
for (map::iterator secKeyValue = m_secKeyValue.begin(); secKeyValue != m_secKeyValue.end(); secKeyValue++)
{
inFile << "[" << secKeyValue->first << "]" << endl;
for (map::iterator keyValue = secKeyValue->second.m_keyValue.begin(); keyValue != secKeyValue->second.m_keyValue.end(); keyValue++)
{
inFile << keyValue->first << "=" << keyValue->second << endl;
}
}
inFile.close();
inFile.clear();
return true;
}
void CIniFile::StrToInt(const string& str, int& num)
{
stringstream stream;
stream << str;
stream >> num;
}
void CIniFile::StrToDouble(const string& str, double& num)
{
stringstream stream;
stream << str;
stream >> num;
}
void CIniFile::strToChar(const string& str, char& num)
{
stringstream stream;
stream << str;
stream >> num;
}
map::size_type CIniFile::GetSize()
{
return m_secKeyValue.size();
}
string CIniFile::FolderPath()
{
char strBuf[256] = { 0 };
GetModuleFileNameA(NULL, strBuf, sizeof(strBuf));
string strTemp = strBuf;
if (strTemp.empty())
return strTemp;
strTemp = strReplaceAll(strTemp, "\\", "/");
string::size_type pos = strTemp.rfind("/");
if (string::npos != pos)
strTemp = strTemp.substr(0, pos);
else
strTemp = "";
return strTemp;
}
//返回一个不含strOld
string CIniFile::strReplaceAll(const string& strResource, const string& strOld, const string& strNew)
{
string::size_type pos = 0;
string strTemp = strResource;
do
{
if ((pos = strTemp.find(strOld)) != string::npos)
{
strTemp.replace(pos, strOld.length(), strNew);
}
} while (pos != string::npos);
return strTemp;
}
// Test.cpp
#include "stdafx.h"
#include "IniFile.h"
#define SERVERINI "/ServerIni.ini"
class CServerIni
{
public:
struct Server
{
string m_serverIp;
int m_serverPort;
int m_serverTimeOut;
};
struct Database
{
string m_dataIp;
string m_dataUserName;
string m_dataName;
string m_dataPassWd;
};
Server m_server;
Database m_database;
};
int _tmain(int argc, _TCHAR* argv[])
{
CIniFile iniFile;
string strIniPath = iniFile.FolderPath();
strIniPath += SERVERINI;
iniFile.LoadFromIni(strIniPath);
if (0 == iniFile.GetSize())
return 0;
CServerIni serIni;
serIni.m_server.m_serverIp = iniFile.GetValue("Server", "ServerIP");
iniFile.StrToInt(iniFile.GetValue("Server", "Port"), serIni.m_server.m_serverPort);
iniFile.StrToInt(iniFile.GetValue("Server", "Timeout"), serIni.m_server.m_serverTimeOut);
serIni.m_database.m_dataIp = iniFile.GetValue("Database", "DBIP");
serIni.m_database.m_dataName = iniFile.GetValue("Database", "DBName");
serIni.m_database.m_dataUserName = iniFile.GetValue("Database", "UsrName");
serIni.m_database.m_dataPassWd = iniFile.GetValue("Database", "UsrPassWd");
return 0;
}