一個手工讀寫INI文件的類(二)

(讀者可以點擊這裏獲得源代碼,注意解壓後將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;
 
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章