读取配置文件

大家都应该知道读取配置文件可以使用系统api GetPrivateProfileString ()(函数原型如下),我原先也对其打包成了一个类,但是今天要使用的时候,竟然出问题了(以前没有出过错的),试了几次还是没有什么效果,一气之下自己动手写了一个。

DWORD GetPrivateProfileString(
  LPCTSTR lpAppName,
  LPCTSTR lpKeyName,
  LPCTSTR lpDefault,
  LPTSTR lpReturnedString,
  DWORD nSize,
  LPCTSTR lpFileName
)

呵呵,无聊的人嘛。其中考虑到的因素有:

1. 有人喜欢写 key=value,而有人喜欢key = value,中间空格情况必须要处理。

2. 有的配置文件中,每个section之间加上一个空行,这不能不考虑。

3. 为了增快速度,我减少了读取文件次数,本来是想,每读取一个键的时候,记录键及其键值的,但是测试结果表明,不如一次读取的快(牺牲空间来达到性能--很常规的做法)

代码贴在下面,测试通过:

/******************************************************************************
PrivateProfile.h
Written by DS
  in 09.03.2005
This class is used to simplified read the profiles
******************************************************************************/

#ifndef DARKSTAR_INITIALIZE_FILE_H
#define DARKSTAR_INITIALIZE_FILE_H
#include "afxcoll.h"
#include "afxtempl.h"
#include "Afx.h"

class CPrivateProfile
{
public:
 CPrivateProfile (void);
 ~CPrivateProfile (void);

 CPrivateProfile (LPCTSTR file);
 int SetProfile (LPCTSTR file);

 int GetInt (LPCTSTR section, LPCTSTR key, int nDefault = -1);
 CString GetString (LPCTSTR section, LPCTSTR key, CString const& strDefault = "");

 void GetAllKeys ();
 //void GetAllKeys (CMapStringToString& map);
 void GetSectionKeys (LPCTSTR section);
 //void GetSectionKeys (LPCTSTR section, CMapStringToString& map);

 int GetTotalKeys ();
protected:
 CFile proFile;

 CList <CString> sections;
 CMapStringToString keyMap;

 bool bInit;
};
#endif //DARKSTAR_INITIALIZE_FILE_H

//PrivateProfile.cpp
#include "StdAfx.h"
#include "PrivateProfile.h"
#include <iostream>
using namespace std;

CPrivateProfile::CPrivateProfile(void)
{
 bInit = false;
 keyMap.RemoveAll ();
}

CPrivateProfile::~CPrivateProfile(void)
{
 proFile.Close ();
 keyMap.RemoveAll ();
}

CPrivateProfile::CPrivateProfile (LPCTSTR file)
{
 if (!proFile.Open (file, CFile::modeReadWrite))
  exit (-1);
 keyMap.RemoveAll ();
}

int CPrivateProfile::SetProfile (LPCTSTR file)
{
 if (!proFile.Open (file, CFile::modeReadWrite))
  return -1;
 keyMap.RemoveAll ();
 GetAllKeys ();
 return 0;
}

void CPrivateProfile::GetAllKeys ()
{
 proFile.SeekToBegin ();
 int size = 2048;
 char* buf;
 int len;
 //Read all context of the file into the memory
 while (true) {
  proFile.SeekToBegin ();
  buf = new char[size];
  memset (buf, 0, size);
  len = proFile.Read (buf, size);
  if (len + 1 < size) {//reach to end of file
   break;
  }
  delete[] buf;
  size *= 2;
 }
 if (buf[len - 1] != '/n')
  buf[len] = '/n';
 
 int pos = 0;
 int offset = 0;
 CString section;
 CString key;
 CString value;
 while (buf[pos] != 0) {
  if (buf[offset] == '/n') { //Null line
   cout << "NULL line offset = " << offset << endl;
   pos++;
   offset = pos;
   continue;
  }
  if (buf[pos] != '/n') {//now line terminator
   pos++;
   continue;
  }
  //line
  CString line (buf + offset, pos - offset);
  //cout << "buf[offset]:" << buf[offset];
  if (pos < len);
   pos++;
  offset = pos;
  //cout << "Deal with line :" << (LPCTSTR) line << endl;
  line.Trim ();
  //cout << "After Trim () :" << (LPCTSTR) line << endl;
  //If this line
  if (line[0] == '[' && line[line.GetLength () - 1] == ']') {
   section = line.Mid (1, line.GetLength () - 2);
   sections.AddTail (section);
   //cout << "Section : " << (LPCTSTR) section << endl;
   continue;
  }
  int tpos = line.Find ('=');
  if (-1 == tpos || 0 == tpos || line.GetLength () - 1 == tpos) { //invalid position of '='
   continue;
  }
  key = section;
  key += "-";
  key += line.Left (tpos);
  key.Trim ();
  value = line.Right (line.GetLength () - tpos - 1);
  value.Trim ();
  //cout << "Key : " << (LPCTSTR)key << "-> Value : " << (LPCTSTR)value << endl;
  keyMap.SetAt (key, value);
 }
 bInit = true;
}

void CPrivateProfile::GetSectionKeys (LPCTSTR section)
{
 proFile.SeekToBegin ();
 int size = 2048;
 char* buf;
 int len;
 //Read all context of the file into the memory
 while (true) {
  proFile.SeekToBegin ();
  buf = new char[size];
  memset (buf, 0, size);
  len = proFile.Read (buf, size);
  if (len < size) {//reach to end of file
   break;
  }
  delete[] buf;
  size *= 2;
 }
 char* des = new char[strlen (section) + 3];
 sprintf (des, "[%s]", section);
 char* p = strstr (buf, des);
 if (NULL == p)
  return ;
 p = strchr (p, '/n');

 int pos = p - buf + 1;
 int offset = pos;
 CString key;
 CString value;
 while (buf[pos] != 0) { 
  if (buf[pos] == '[') //stop, when ge to the next section
   break;
  if (buf[pos] != '/n') {//now line terminator
   pos++;
   continue;
  }

  if (pos == offset) { //Null line
   offset++;
   pos++;
   continue;
  }
  //line
  CString line (buf + offset, pos - offset);
  pos++;
  offset = pos;
  line.Trim ();
  int tpos = line.Find ('=');
  if (-1 == tpos || 0 == tpos || line.GetLength () - 1 == tpos) { //invalid position of '='
   continue;
  }
  key = section;
  key += "-";
  key += line.Left (tpos);
  value = line.Right (line.GetLength () - tpos - 1);
  keyMap.SetAt (key, value);
 }
}

CString CPrivateProfile::GetString (LPCTSTR section, LPCTSTR key, CString const& strDefault)
{
 if (!bInit)
  GetAllKeys ();
 CString s = section;
 s += '-';
 s += key;

 CString value;
 if (keyMap.Lookup (s, value))
  return value;
 return strDefault;
}

int CPrivateProfile::GetInt (LPCTSTR section, LPCTSTR key, int nDefault)
{
 if (!bInit)
  GetAllKeys ();
 CString s = section;
 s += '-';
 s += key;

 CString value;
 if (keyMap.Lookup (s, value))
  return atoi ((LPCTSTR) value);
 return nDefault;
}

int CPrivateProfile::GetTotalKeys ()
{
 if (!bInit)
  GetAllKeys ();
 return keyMap.GetSize ();
}

测试的主函数被我改了n次,基本上就是测试各种情况,没什么值得贴上来的东西。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值