首先看看倆個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());
}