参考博文http://hi.baidu.com/xiao___q/item/57dccd41e5a7c7f0dd0f6c29
我写的这个解析比较简单,因为自己项目用的ini文件中只是记录配置文件的存放位置,格式一般就是XXXCFG=XXX.txt这样
所以简单的解析了一下,主要函数是这样写的
//key是等号左边的值 value是等号右边的值
std::map<std::string,std::string> m_Lines;//用来记录读进内存的数据
//解析函数
bool CIniFile::Init(const char* pCfgFilePath)//传入ini文件路径以及文件名
{
bool bRet = false;
tempNil = "";
unsigned char* pBuffer = NULL;
unsigned long bufferSize = 0;
pBuffer = CCFileUtils::sharedFileUtils()->getFileData(pCfgFilePath, "r", &bufferSize);
if (pBuffer)
{
int nLineLength = 0;
string lineStr="";//一行数据
for(unsigned long i = 0; i < bufferSize; i ++)//遍历读进来的所有字符
{
if(pBuffer[i] != '\r' && pBuffer[i] !='\n' && pBuffer[i] !='\0')//如果该字符不是回车、换行、结束符,则把这个字符加入本行str变量中
{
lineStr += pBuffer[i];
nLineLength ++;
}
else//已经读了一行
{
if(nLineLength > 0)//读取了一行有字符的数据
{
StringReplace(lineStr, " ", "");//将该行数据中的空格全部删除(自定义函数)
if(lineStr.length() > 0)//如果剔除空格后该行字符串中仍有数据
{
ArString lineAr;//ArString是自定义类型,后面会给出定义
SplitString(lineStr,"=",lineAr);//按'='号分割字符串(自定义函数)
if(lineAr.size() >= 2)//如果字符串能分割成两个串 则是有效行
{
string postfix(lineAr[1]);//将'='号右边的串赋值给postfix
if(postfix.length() > 3)
{
postfix = postfix.substr(postfix.size() - 3, postfix.size()); // 截取最后三个
//因为项目的数据分了文件夹存储,所以要将ini中的一些配置信息在读进来时添加路径
if (strcmp("txt", postfix.c_str()) == 0)//如果是txt路径
{
lineAr[1] = m_Lines["TXTPATH"] + lineAr[1];
}
if (strcmp("png", postfix.c_str()) == 0)//如果是png路径
{
lineAr[1] = m_Lines["IMAGEPATH"] + lineAr[1];
}
if (strcmp("jpg", postfix.c_str()) == 0)//如果是jpg路径
{
lineAr[1] = m_Lines["IMAGEPATH"] + lineAr[1];
}
}
m_Lines[lineAr[0]] = lineAr[1]; //存入map变量中
}
}
nLineLength = 0;
lineStr = "";
}
else
continue;
}
}
bRet = true;
}
return bRet;
}
//一些辅助函数
typedef std::vector<std::string> ArString;
std::string& StringReplace(std::string& strBig, const std::string& strsrc, const std::string& strdst)
{
std::string::size_type pos = 0;
std::string::size_type srclen = strsrc.size();
std::string::size_type dstlen = strdst.size();
while( (pos = strBig.find(strsrc, pos)) != std::string::npos)
{
strBig.replace(pos, srclen, strdst);
pos += dstlen;
}
return strBig;
}
void SplitString(const std::string& strSrc, const std::string& strFind, ArString& arSplit)
{
int st = 0;
int npos = strSrc.find(strFind);
if (npos == -1)
{
arSplit.push_back(strSrc);
return;
}
while(npos > -1)
{
arSplit.push_back(strSrc.substr(st, npos - st));
st = npos + strFind.size();
npos = strSrc.find(strFind, npos + 1);
if (npos <= -1)
{
arSplit.push_back(strSrc.substr(st, npos - st));
break;
}
}
}
写好上述函数以后,我们需要再写一个获取文件内容的函数,以便在别的类中能获取ini中的值
std::string& CIniFile::GetValue(const std::string& strKey)
{
std::map<std::string,std::string>::iterator it = m_Lines.find(strKey);
if(it != m_Lines.end())
return it->second;
else
return tempNil;//类中一个数据成员,值为""
}
将CIniFile做成一个单例类,在其他类中就可以同包涵头文件访问ini中的数据了
源码已上传至资源中