首先看看俩个API :
1.GetPrivateProfileSectionNames(),顾名思义获取段名,但很奇怪的是只能得到第一个段名。但有木有观察他的返回值是什么? OK,到这里我们调试一下会发现第一个段名后边有个'\0',当然这个东西是字符串的结束标志嘛!OK,我们再往下一个地址看看是什么,也就是'\0'后面的东东! NM,原来的二个段名在这里。OK,一个结论出来了,其实他返回了所有的段名,不过每个段名之间都是用'\0'隔离开的。剩下的就是解析问题啦……
2.GetPrivateProfileSection(),当然和前面思路一样,他返回给我们的是所有键值,当然键值和键值之间也是用'\0'隔离开的!
我简单封装了一个类:
#include <vector>
#include <string>
using namespace std;
class CIniFile
{
public:
CIniFile();
CIniFile(const char* sPath);
virtual ~CIniFile();
void LoadFile(const char* sPath ); //文件路径
void GetSectionNames(vector<string> &ar);/*得到所有段*/
void GetKeyNames(const char* lpSection/*段名*/, vector<string> &ar);//得到某段下所有key名称
DWORD GetValue(const char *lpSection/*段名*/, const char *sKey/*Key值*/, string& key);//得到可以值
void GetKey_Value(const char* lpSection/*段名*/, vector<string> &ar );/*得到该段下的所有key-value*/
BOOL Write(const char* lpSection, const char* lpKey, const char* lpValue);//写入键值
BOOL DeleteSection(const char* lpSection);//删除段
BOOL DeleteKey(const char* lpSection, const char* lpKey);//删除key
protected:
DWORD GetSectionNames(char* lpBuffer, DWORD dwBufSize);//返回字符总数
DWORD GetKey_Value(const char* lpSection, char* lpBuffer, DWORD dwBufSize);//返回字符总数
BOOL ParseString( char* buff, vector<string> &ar );//解析出段、键值
protected:
string m_sPath;
};
cpp文件:
#define DEF_PROFILE_THRESHOLD 512
CIniFile::CIniFile()
{
}
CIniFile::CIniFile( const char* sPath ):m_sPath(sPath)
{
}
CIniFile::~CIniFile()
{
}
void CIniFile::LoadFile(const char* sPath )
{
m_sPath = sPath;
}
void CIniFile::GetSectionNames( vector<string> &ar )
{
const DWORD LEN = GetSectionNames(NULL, 0);
if (LEN == 0)
return;
char* psz = new char[LEN + 1];
GetSectionNames(psz, LEN);
ParseString(psz, ar);
delete [] psz;
}
DWORD CIniFile::GetSectionNames(char* lpBuffer, DWORD dwBufSize)
{
if (lpBuffer == NULL)
{
// just calculate the required buffer size
DWORD dwLen = DEF_PROFILE_THRESHOLD;
char* psz = new char[dwLen + 1];
DWORD dwCopied = ::GetPrivateProfileSectionNames(psz, dwLen, m_sPath.c_str());
while (dwCopied + 2 >= dwLen)
{
dwLen += DEF_PROFILE_THRESHOLD;
delete [] psz;
psz = new char[dwLen + 1];
dwCopied = ::GetPrivateProfileSectionNames(psz, dwLen, m_sPath.c_str());
}
delete [] psz;
return dwCopied + 2;
}
else
{
return ::GetPrivateProfileSectionNames(lpBuffer, dwBufSize, m_sPath.c_str());
}
}
void CIniFile::GetKey_Value(const char* lpSection/*段名*/, vector<string> &ar )
{
DWORD Len = GetKey_Value(lpSection, NULL, 0);
char* psz = new char[Len + 1];
GetKey_Value(lpSection, psz, Len);
ParseString(psz, ar);
delete [] psz;
}
DWORD CIniFile::GetKey_Value(const char* lpSection, char* lpBuffer, DWORD dwBufSize)
{
if (lpBuffer != NULL)
*lpBuffer = _T('\0');
if (lpSection == NULL)
return 0;
if (lpBuffer == NULL)
{
// just calculate the required buffer size
DWORD dwLen = DEF_PROFILE_THRESHOLD;
char* psz = new char[dwLen + 1];
DWORD dwCopied = ::GetPrivateProfileSection(lpSection, psz, dwLen, m_sPath.c_str());
while (dwCopied + 2 >= dwLen)
{
dwLen += DEF_PROFILE_THRESHOLD;
delete [] psz;
psz = new char[dwLen + 1];
dwCopied = ::GetPrivateProfileSection(lpSection, psz, dwLen, m_sPath.c_str());
}
delete [] psz;
return dwCopied + 2;
}
else
{
return ::GetPrivateProfileSection(lpSection, lpBuffer, dwBufSize, m_sPath.c_str());
}
}
BOOL CIniFile::ParseString( char* buff, vector<string> &ar )
{
if (buff == NULL)
return FALSE;
char* p = buff;
DWORD dwLen = _tcslen(p);
while (dwLen > 0)
{
ar.push_back(string(p));
p = &p[dwLen + 1];
dwLen = _tcslen(p);
}
return TRUE;
}
void CIniFile::GetKeyNames(const char* lpSection/*段名*/, vector<string> &ar )
{
vector<string> key_value;
GetKey_Value(lpSection, key_value);//先得到所有的key_value,然后解析出来
int num = key_value.size();
for(int i=0; i<num; i++)
{
int pos = key_value[i].find('=', 0);
if(-1 == pos)
ar.push_back(key_value[i]);
else
ar.push_back(key_value[i].substr(0, pos));
}
}
DWORD CIniFile::GetValue(const char *lpSection/*段名*/,const char *sKey/*Key值*/, string& key)
{
if (lpSection == NULL || sKey == NULL)
return FALSE;
char val[512]={'\0'};
DWORD ret = GetPrivateProfileString(lpSection, sKey, "", val, 512, m_sPath.c_str());
key = val;
return ret;
}
BOOL CIniFile::Write( const char* lpSection, const char* lpKey, const char* lpValue )
{
if (lpSection == NULL || lpKey == NULL)
return FALSE;
return ::WritePrivateProfileString(lpSection, lpKey, lpValue == NULL ? _T("") : lpValue, m_sPath.c_str());
}
BOOL CIniFile::DeleteSection(const char* lpSection)
{
return ::WritePrivateProfileString(lpSection, NULL, _T(""), m_sPath.c_str());
}
BOOL CIniFile::DeleteKey(const char* lpSection, const char* lpKey)
{
return ::WritePrivateProfileString(lpSection, lpKey, NULL, m_sPath.c_str());
}