// cross-platform ini parser by uniqs
#include <string>
#if 0
#define INI_FILE_USE_C11
#endif
#ifdef INI_FILE_USE_C11
#include <unordered_map>
#else
#include <map>
#endif
class CINIParser
{
#ifdef INI_FILE_USE_C11
typedef std::unordered_map<std::string, std::string> MAPKeyValues;
typedef std::unordered_map < std::string, MAPKeyValues > MAPSectionKeyValues;
#else
typedef std::map<std::string, std::string> MAPKeyValues;
typedef std::map < std::string, MAPKeyValues > MAPSectionKeyValues;
#endif
MAPSectionKeyValues m_mapSectionKeyValues;
bool IsBlank(char c){ return c == ' ' || c == '\t'; }
public:
CINIParser();
~CINIParser();
public:
bool ReadFromFile(const char* pszFile);
bool GetIniFileString(const char* pszSection, const char* pszKey, char szValue[], int nSize, const char* pszDefault);
int GetIniFileInt(const char* pszSection, const char* pszKey, int nDefault);
};
// cross-platform ini parser by uniqs
#include "ini_parser.h"
#include <string.h>
#include <stdlib.h>
#include <fstream>
CINIParser::CINIParser()
{
m_mapSectionKeyValues.clear();
}
CINIParser::~CINIParser()
{
m_mapSectionKeyValues.clear();
}
bool CINIParser::ReadFromFile(const char* pszFile)
{
std::ifstream ifs(pszFile);
const int nTmpBufSize = 2048;
char szTmp[nTmpBufSize];
std::string strSection;
while (ifs.getline(szTmp, nTmpBufSize))
{
std::string strTmp = szTmp;
if (strTmp.empty())
{
continue;
}
std::string::size_type pos_valid_end = strTmp.find(';');
if (pos_valid_end != std::string::npos)
{
while (pos_valid_end > 0 && IsBlank(strTmp[pos_valid_end]))
{
--pos_valid_end;
}
strTmp = strTmp.substr(0, pos_valid_end);
}
else
{
pos_valid_end = strTmp.size() - 1;
}
std::string::size_type pos_valid_begin = 0;
while (pos_valid_begin < pos_valid_end && IsBlank(strTmp[pos_valid_begin]))
{
++pos_valid_begin;
}
if (pos_valid_begin >= pos_valid_end)
{
continue;
}
std::string::size_type pos_section1 = strTmp.find('[');
if (pos_section1 != std::string::npos)
{
std::string::size_type pos_section2 = strTmp.find(']');
if (pos_section2 == std::string::npos)
{
ifs.close();
return false;
}
if (pos_section2 < pos_section1)
{
ifs.close();
return false;
}
strSection = strTmp.substr(pos_section1 + 1, pos_section2 - pos_section1 - 1);
m_mapSectionKeyValues[strSection] = MAPKeyValues();
continue;
}
std::string::size_type pos_split = strTmp.find('=');
if (pos_split != std::string::npos)
{
std::string::size_type pos_key1 = 0;
while (pos_key1 < pos_split && IsBlank(strTmp[pos_key1]))
{
++pos_key1;
}
std::string::size_type pos_key2 = pos_split - 1;
while (pos_key2 > pos_key1 && IsBlank(strTmp[pos_key2]))
{
--pos_key2;
}
std::string strKey = strTmp.substr(pos_key1, pos_key2 + 1);
std::string::size_type len = strTmp.size();
std::string::size_type pos_value1 = pos_split + 1;
while (pos_value1 < len - 1 && IsBlank(strTmp[pos_value1]))
{
++pos_value1;
}
std::string::size_type pos_value2 = len - 1;
while (pos_value2 > pos_value1 && IsBlank(strTmp[pos_value2]))
{
--pos_value2;
}
std::string strValue = strTmp.substr(pos_value1, pos_value2);
m_mapSectionKeyValues[strSection][strKey] = strValue;
continue;
}
ifs.close();
return false;
}
ifs.close();
return true;
}
bool CINIParser::GetIniFileString(const char* pszSection, const char* pszKey, char szValue[], int nSize, const char* pszDefault)
{
if (pszSection&& pszKey)
{
std::string strSection = pszSection;
std::string strKey = pszKey;
MAPSectionKeyValues::const_iterator itSection = m_mapSectionKeyValues.find(strSection);
if (itSection != m_mapSectionKeyValues.end())
{
MAPKeyValues::const_iterator itKV = itSection->second.find(strKey);
if (itKV != itSection->second.end())
{
strncpy(szValue, itKV->second.c_str(), nSize);
return true;
}
}
}
strncpy(szValue, pszDefault, nSize);
return false;
}
int CINIParser::GetIniFileInt(const char* pszSection, const char* pszKey, int nDefault)
{
if (pszSection&& pszKey)
{
std::string strSection = pszSection;
std::string strKey = pszKey;
MAPSectionKeyValues::const_iterator itSection = m_mapSectionKeyValues.find(strSection);
if (itSection != m_mapSectionKeyValues.end())
{
MAPKeyValues::const_iterator itKV = itSection->second.find(strKey);
if (itKV != itSection->second.end())
{
return atoi(itKV->second.c_str());
}
}
}
return nDefault;
}
// cross-platform ini parser by uniqs
// main.cpp
#include "ini_parser.h"
#include <iostream>
using namespace std;
int main()
{
CINIParser oParser;
oParser.ReadFromFile("Scene.ini");
const int nBufSize = 1024;
char szTmp[nBufSize];
if (oParser.GetIniFileString("scene", "SmallBird", szTmp, nBufSize, ""))
{
cout << szTmp << endl;
}
int ChestBird = oParser.GetIniFileInt("scene", "ChestBird", 0);
cout << ChestBird << endl;
return 0;
}
INI文件:
[scene]
Name = 深海捕鱼
SceneID= 2,4,6
SmallBird =2,3,4,5,6
NormalBird =8,9,10,11,12
BigBird=13,14,15,16,26
HugeBird=18,19,20,21
ChestBird=24
CleanBird=0,1,2,3,4,5,6
SmallCleanBird=8,9,10,11
GroupBird=0,1
SceneBird1=26,18,19,21
SceneBird2=0,2,3
SceneBird3=4,5,6,8,9,10,11
SmallBirdElapseStart = 5
SmallBirdElapseEnd = 14
NormalBirdElapseStart = 8
NormalBirdElapseEnd = 16
;
;
;
;
;
;
;
;
;
BigBirdElapseStart = 8
BigBirdElapseEnd = 20
GroupBirdElapseStart = 10;
GroupBirdElapseEnd = 17;
HugeBirdElapseStart = 25;
HugeBirdElapseEnd = 35;
SmallCleanSweepBirdElapseStart = 20;
SmallCleanSweepBirdElapseEnd = 36;
CleanSweepBirdElapseStart = 30;
CleanSweepBirdElapseEnd = 40;
ChestBirdElapseStart = 200;
ChestBirdElapseEnd = 600;
LINUX编译脚本:
g++ -g ini_parser.cpp Source.cpp