(讀者可以點擊這裏獲得源代碼,注意解壓後將boot.ini拷貝到E:/,以便程序運行找到文件)
頭文件CfgData.h
// CfgData.h: interface for the CCfgData class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CFGDATA_H__A40CDB9A_0E44_49E6_A460_505D76BA6414__INCLUDED_)
#define AFX_CFGDATA_H__A40CDB9A_0E44_49E6_A460_505D76BA6414__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CCfgData
{
protected:
//組到配置數據的映射
CMapStringToPtr m_StrMapMap;
//當前組
CString m_strGroup;
public:
//構造配置數據
CCfgData();
//析構配置數據
virtual ~CCfgData();
//從文件加載配置數據
/*
參數: LPCTSTR strFileName 加載文件的名稱
返回值:無
*/
void LoadCfgData(LPCTSTR strFileName);
//將配置數據保存到文件
/*
參數: LPCTSTR strFileName 保存文件的名稱
返回值:成功返回TRUE 失敗返回FALSE
*/
BOOL SaveCfgData(LPCTSTR strFileName);
//將配置數據保存到字符串
/*
參數: CString* pstr 要保存的字符串指針
返回值:成功返回TRUE 失敗返回FALSE
*/
BOOL SaveToStr(CString* pstr);
//設置當前讀取的組
/*
參數: 當前組名稱
返回值:無
*/
void SetGroup(LPCTSTR strGroup);
//修改或者添加一條當前組中的數據
/*
參數: LPCTSTR strKey 要修改的數據的鍵值
LPCTSTR strValue要修改的數據的內容
返回值:
備註: 如果當前組在配置數據中存在,則修改或者添加該組對應鍵值的數據,如果當前組災配置數據中不存在,則先創建該組
*/
BOOL SetData(LPCTSTR strKey,LPCTSTR strValue);
//得到當前組中對應鍵值中字符串類型的數據
/*
參數: LPCTSTR strKey 要得到的數據的鍵值
LPCTSTR strValue要得到的數據的內容
返回值:找到數據返回TRUE,否則返回FALSE
*/
virtual BOOL GetStrData(LPCTSTR strKey,CString &strValue);
//得到long型的數據
/*
參數: LPCTSTR strKey 要得到的數據的鍵值
long lValue 要得到的數據的值
返回值:找到數據返回TRUE,否則返回FALSE
*/
virtual BOOL GetLongData(LPCTSTR strKey,long &lValue);
protected:
//釋放配置數據所佔用的內存
/*
參數: 無
返回值:無
*/
void RemoveAll();
};
#endif // !defined(AFX_CFGDATA_H__A40CDB9A_0E44_49E6_A460_505D76BA6414__INCLUDED_)
源文件CfgData.cpp
// CfgData.cpp: implementation of the CCfgData class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CfgData.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//構造配置數據
CCfgData::CCfgData()
{
//初始化配置數據
m_strGroup="設置";
}
//析構配置數據
CCfgData::~CCfgData()
{
RemoveAll();
}
//釋放配置數據所佔用的內存
/*
參數: 無
返回值:無
*/
void CCfgData::RemoveAll()
{
POSITION pos=m_StrMapMap.GetStartPosition();
while(pos)
{
CMapStringToString* pStrMap;
CString str;
m_StrMapMap.GetNextAssoc(pos,str,(void*&)pStrMap);
if(pStrMap!=NULL)
{
pStrMap->RemoveAll();
//刪除掉CString--> 指針映射中的指針
delete pStrMap;
}
}
m_StrMapMap.RemoveAll();
}
//從文件加載配置數據
/*
參數: LPCTSTR strFileName 加載文件的名稱
返回值:無
*/
void CCfgData::LoadCfgData(LPCTSTR strFileName)
{
int iReadLen=0;
CString str[3];
int iState=0;//0:正在讀入鍵值 1:正在讀入內容 2:正在讀入組
unsigned char ch; //正在讀取的字符
//清空配置數據
RemoveAll();
CFile file;
file.Open(strFileName, CFile::modeRead);
file.Seek(0,CFile::begin);
str[0]="";//存放鍵值字符串
str[1]="";//存放內容字符串
str[2]="";//存放組字符串
//字符串到字符串的映射,保存鍵值和內容
CMapStringToString* pStrMap=NULL;
do
{
iReadLen=file.Read(&ch,1);
if(iReadLen!=0)
{
//處理中文
if(ch>0x80)//中文
{
str[iState]+=ch;
iReadLen=file.Read(&ch,1);
if(iReadLen!=0)
{
str[iState]+=ch;
}
}else
{
switch(ch)
{
//處理'['讀入組字符串
case '[':
str[0].TrimLeft();
str[0].TrimRight();
str[1].TrimLeft();
str[1].TrimRight();
//確認鍵值和內容數據爲空,否則可能是鍵值和內容中的符號
if(str[0]==""&&str[1]=="")
{
pStrMap=NULL;
iState=2;
str[2]="";
}else
{
str[iState]+=ch;
}
break;
//處理']'組字符串讀入完畢
case ']':
//確認讀入的是組的字符串數據
str[2].TrimLeft();
str[2].TrimRight();
if(iState==2&&str[2]!="")
{
iState=0;
//新建一個組下的鍵值-->內容映射,放入該組
pStrMap=new CMapStringToString;
m_StrMapMap.SetAt(str[2],pStrMap);
}else
{
str[iState]+=ch;
}
break;
case '=':
//開始讀入內容
iState=1;
str[1]="";
break;
//處理回車和註釋
case ';':
case 0x0d:
case 0x0a:
iState=0;
//鍵值非空
str[0].TrimLeft();
str[0].TrimRight();
str[1].TrimLeft();
str[1].TrimRight();
if(str[0]!=""&&pStrMap!=NULL)
{
pStrMap->SetAt((LPCTSTR)str[0],(LPCTSTR)str[1]);
}
//處理完清空數據
str[0]="";
str[1]="";
//註釋的話繼續讀入直到文件結束或者碰到回車符號
if(ch==';')
{
while((iReadLen=file.Read(&ch,1))>0)
{
//如果遇到回車符號,終止,並且將當前位置退回
if(ch==0x0d||ch==0x0a)
{
file.Seek(-1,CFile::current);
break;
}
}
}
break;
default:
//普通字符,添加進入相應位置
str[iState]+=ch;
break;
}
}
}
}while(iReadLen!=0);
file.Close();
}
//設置當前讀取的組
/*
參數: 當前組名稱
返回值:無
*/
void CCfgData::SetGroup(LPCTSTR strGroup)
{
m_strGroup=strGroup;
}
//得到當前組中對應鍵值中字符串類型的數據
/*
參數: LPCTSTR strKey 要得到的數據的鍵值
LPCTSTR strValue要得到的數據的內容
返回值:找到數據返回TRUE,否則返回FALSE
*/
BOOL CCfgData::GetStrData(LPCTSTR strKey, CString &strValue)
{
CMapStringToString* pStrMap=NULL;
//尋找當前組
if(m_StrMapMap.Lookup(m_strGroup,(void*&)pStrMap))
{
if(pStrMap->Lookup(strKey,strValue))
return TRUE;
return FALSE;
}
return FALSE;
}
//得到long型的數據
/*
參數: LPCTSTR strKey 要得到的數據的鍵值
long lValue 要得到的數據的值
返回值:找到數據返回TRUE,否則返回FALSE
*/
BOOL CCfgData::GetLongData(LPCTSTR strKey, long &lValue)
{
CString str;
//得到對應的字符串數據
if(CCfgData::GetStrData(strKey, str))
{
lValue=atoi((LPCTSTR)str);
return TRUE;
}
return FALSE;
}
//修改或者添加一條當前組中的數據
/*
參數: LPCTSTR strKey 要修改的數據的鍵值
LPCTSTR strValue要修改的數據的內容
返回值:
備註: 如果當前組在配置數據中存在,則修改或者添加該組對應鍵值的數據,如果當前組災配置數據中不存在,則先創建該組
*/
BOOL CCfgData::SetData(LPCTSTR strKey, LPCTSTR strValue)
{
CMapStringToString* pStrMap=NULL;
//如果存在該組,直接加入或者修改
if(m_StrMapMap.Lookup(m_strGroup,(void*&)pStrMap))
{
pStrMap->SetAt(strKey,strValue);
return TRUE;
}else
{
//創建該組
pStrMap=new CMapStringToString;
m_StrMapMap.SetAt(m_strGroup,pStrMap);
pStrMap->SetAt(strKey,strValue);
return TRUE;
}
}
//將配置數據保存到文件
/*
參數: LPCTSTR strFileName 保存文件的名稱
返回值:成功返回TRUE 失敗返回FALSE
*/
BOOL CCfgData::SaveCfgData(LPCTSTR strFileName)
{
CFile file;
if(!file.Open(strFileName,CFile::modeCreate|CFile::modeWrite))
return FALSE;
POSITION pos=m_StrMapMap.GetStartPosition();
char ch[6]="[]/r/n=";//特殊符號
CString str[3];
while(pos)
{
CMapStringToString* pStrMap;
m_StrMapMap.GetNextAssoc(pos,str[2],(void*&)pStrMap);
if(pStrMap!=NULL)
{
//寫入組
file.Write(&ch[0],1);
file.Write((LPSTR)(LPCTSTR)str[2],str[2].GetLength());
file.Write(&ch[1],1);
file.Write(&ch[2],2);
POSITION pos1=pStrMap->GetStartPosition();
while(pos1)
{
//寫入鍵值和內容
pStrMap->GetNextAssoc(pos1,str[0],str[1]);
file.Write((LPSTR)(LPCTSTR)str[0],str[0].GetLength());
file.Write(&ch[4],1);
file.Write((LPSTR)(LPCTSTR)str[1],str[1].GetLength());
file.Write(&ch[2],2);
}
}
}
file.Close();
return TRUE;
}
//將配置數據保存到字符串
/*
參數: CString* pstr 要保存的字符串指針
返回值:成功返回TRUE 失敗返回FALSE
備註: 程序流程和上面基本相同,不同的保存進入字符串中
*/
BOOL CCfgData::SaveToStr(CString *pstr)
{
if(pstr==NULL)return FALSE;
*pstr="";
POSITION pos=m_StrMapMap.GetStartPosition();
CString str[4];
while(pos)
{
CMapStringToString* pStrMap;
m_StrMapMap.GetNextAssoc(pos,str[2],(void*&)pStrMap);
if(pStrMap!=NULL)
{
str[3]=*pstr;
pstr->Format("%s[%s]/r/n",str[3],str[2]);
POSITION pos1=pStrMap->GetStartPosition();
while(pos1)
{
pStrMap->GetNextAssoc(pos1,str[0],str[1]);
str[3]=*pstr;
pstr->Format("%s%s=%s/r/n",str[3],str[0],str[1]);
}
}
}
return TRUE;
}