利用宏简化配置文件读写的类

来源:互联网 发布:java微信开发获取code 编辑:程序博客网 时间:2024/04/27 20:44

 

利用宏简化配置文件读写的类

 

作者:邓振波

 

代码下载:点击这里

 

应用程序编程过程中一般免不了需要读写配置文件。一般的做法是编写一个配置读写类。

比如需要读取和保存服务器的绑定地址和端口的配置

大致形式如下:

#define SectionServer "Server"

#define KeyPort           "Port"

#define KeyAddress     "Address" 

 

class CAppConfig

{

    int GetServePort()

   {

      return GetPrivateProfileInt(SectionServer , KeyPort, 80, m_strConfigFileName);

   };

 

   int GetServerAddress();

   {

       ......

    };

 

   int SetServerPort(const int nPort);

  {

       ......

    };

   int SetServerAddress(const char* pszAddr)

  {

       ......

    };

}

 

 从上面看出,步骤一般如下:

  1、为了方便的不写错段名和键名,一般会定义一批宏,代表段名和键名

  2、写出GetXXX

  3、写出SetXXX

  有多个配置不断重复上面3个步骤,在配置多的情况下面,代码一大堆,写得很烦人。

 

如果我们能充分利用c++的宏、#和##的妙处,则可以把代码写得非常简单。

改造过的代码类似如下

class CAppConfig

{
public:

 DEFINE_INT_CONFIG(Server, Port, 1); 
 DEFINE_STRING_CONFIG(Server, Address, "127.0.0.1"); 
};

 

通过一个宏,无需对段名和键名进行定义,同时生成了GetXXX和SetXXX的函数,同时还支持定义默认值。下面的全部代码。

 

 

#pragma once

//////////////////////////////////////////////////////////////////////////
//
//Created By Dengzhenbo
//Date: 2009-3-12
//
//////////////////////////////////////////////////////////////////////////

 

#include <string>
#include <assert.h>

#define GetConfigValueInt GetPrivateProfileIntA
#define GetConfigValueString GetPrivateProfileStringA
#define SetConfigValueString WritePrivateProfileStringA

 

#define DEFINE_INT_CONFIG(Section, Key, Default) /
 int Get##Section##Key() /
 { /
  return GetConfigValueInt(#Section, #Key, Default, m_strFileName.c_str());  /
 };  /
 int Set##Section##Key(int nValue)  /
 {  /
  char szValue[20];  /
  sprintf_s(szValue, sizeof(szValue), "%d", nValue);  /
  return SetConfigValueString(#Section, #Key, szValue, m_strFileName.c_str());  /
 };
 
#define DEFINE_STRING_CONFIG(Section, Key, Default) /
 std::string Get##Section##Key() /
 { /
  int  nRetCode = 0; /
  char szValue[512] = {0}; /
  std::string strReturn; /
  GetConfigValueString(#Section, #Key, Default, szValue, sizeof(szValue), m_strFileName.c_str());  /
  strReturn = szValue; /
  return strReturn; /
 };  /
 int Set##Section##Key(char* szValue)  /
 {  /
  return SetConfigValueString(#Section, #Key, szValue, m_strFileName.c_str());  /
 };

 


class CConfigBase
{
public:

 CConfigBase()
 {
  m_strFileName = "config.ini";
 };

 CConfigBase(const char* pszFilePath)
 {
  assert(pszFilePath);
  m_strFileName = pszFilePath;
 };

 ~CConfigBase(void){};

 void SetConfigFilePath(const char* pszFilePath)
 {
  assert(pszFilePath);
  m_strFileName = pszFilePath;
 }

 int GetConfigInt(const char* pszSection, const char* pszKey, int nDefaule)
 {
  return GetConfigValueInt(pszSection, pszKey, nDefaule, m_strFileName.c_str());
 };

 int SetConfigInt(const char* pszSection, const char* pszKey, int nValue)
 {
  char szValue[20];
  sprintf_s(szValue, sizeof(szValue), "%d", nValue);
  return SetConfigValueString(pszSection, pszKey, szValue, m_strFileName.c_str());
 };

 std::string GetConfigString(const char* pszSection, const char* pszKey, const char* pszDefaule) //String Value Max Length = 512
 {
  int  nRetCode = 0;
  char szValue[512] = {0};
  std::string strReturn;
  GetConfigValueString(pszSection, pszKey, pszDefaule, szValue, sizeof(szValue), m_strFileName.c_str());
  strReturn = szValue;
  return strReturn;
 };

 int SetConfigString(const char* pszSection, const char* pszKey, const char* pszValue)
 {  
  return SetConfigValueString(pszSection, pszKey, pszValue, m_strFileName.c_str());
 }; 
 
protected:

 std::string m_strFileName;


};

 

 

使用的时候可以这样


class CAppConfig: public CConfigBase
{
public:

 DEFINE_INT_CONFIG(Server, Port, 1); 
 DEFINE_STRING_CONFIG(Server, Address, "127.0.0.1"); 
};

 

上面代码展开宏后,会自动生成GetServerPort、SetServerPort、GetServerAddress和SetServerAddress函数,可以直接调用这4个函数。

 

呵呵,简单吧!!!

 

 

原创粉丝点击