ini文件操作类

mac2022-06-30  36

[转载]   前言:     相信很多朋友在编写自己的程序中,都需要把一些数据先期导入到程序中进行初始化。那么这个时候,比较好的做法就是把你所有的数据写入一个ini文件,然后在程序去读ini文件中的数据对行初始化。   一.INI简介        那么什么是ini文件呢?ini文件是Initialization file的缩写,意即初始化文件。(从名字就可以看出它的功能了吧)。不仅你自己的程序可以使用ini文件,其实windows操作系统也有自己的ini文件---win.ini,保存在%WinDir%\system32目录下。Windows通过该文件对当前操作系统进行配置。     ini文件里的数据的存取是采取的是预先约定好的 “项-值”存储结构,各种数据被分门别类的存储。以下是win.ini 文件的部分内容。 [Mail] MAPI=1 CMC=1 CMCDLLNAME=mapi.dll CMCDLLNAME32=mapi32.dll MAPIX=1 MAPIXVER=1.0.0.1 OLEMessaging=1                       表1 通过以上内容,我们可以看到,ini文件将各种数据分成很多以“[ ]”组成的节,而在每一个“节”中又包含了很多“项”,“项”后面紧跟着一个等号,等号后面则是该项的值。在该例中[Mail]就是一个“节”,MAPI是一个项,1则是MAPI的值。     所以,它的通用形式我们可以总结成: [Section] Key=KeyValue   二.操作ini文件的API windows SDK提供有两组API对ini文件进行读写。 读  写   GetPrivateProfileString GetPrivateProfileInt  WritePrivateProfileString   GetPrivateProfileSection  WritePrivateProfileSection   GetPrivateProfileSectionNames      GetPrivateProfileStruct  WritePrivateProfileStruct                                                                                表2   读  写   GetProfileString GetProfileInt  WriteProfileString   GetProfileSection  WritePrivateProfileSection                                                                                表3     对用户的配置文件来说,一般我们使用的是表2中的函数,这一点从函数中的“private”就可以看出它是针对私有的配置文件的函数(又是废话!)。而表3中的函数则是提供给针对系统配置文件,即win.ini进行操作的函数。现只准备介绍表2中的函数,这也是使用率最高的,表3中的函数操作和表2中的函数操作类同,故略。             现在我们来看看这几个函数的功能: DWORD GetPrivateProfileString(   LPCTSTR lpAppName,           //节名,即Section   LPCTSTR lpKeyName,           //项名,即Key   LPCTSTR lpDefault,                //缺省返回字符串。如lpKeyName未找到,拷贝lpDefault到lpReturnedString   LPTSTR lpReturnedString,       //返回字符串的缓冲地址   DWORD nSize,                       //缓冲大小   LPCTSTR lpFileName             //ini文件路径 ); 功能:根据指定的Section和 Key得到KeyValue,存放在lpReturnedString中 返回:返回拷贝到缓冲中的字符个数。不包括结束符   UINT GetPrivateProfileInt(   LPCTSTR lpAppName,           //节名,即Section   LPCTSTR lpKeyName,           //项名,即Key   INT nDefault,                           //缺省返回整型值。如lpKeyName未找到,函数返回nDefault的值   LPCTSTR lpFileName             //ini文件路径 ); 功能:根据指定的Section和 Key得到整型KeyValue 返回:返回得到的整型KeyValue   BOOL WritePrivateProfileString(   LPCTSTR lpAppName,           //节名,即Section   LPCTSTR lpKeyName,           //项名,即Key   LPCTSTR lpString,                  //要写入的字符串   LPCTSTR lpFileName             //ini文件路径 ); 功能:向指定的Section和 Key写入KeyValue。       如果lpString为NULL,则删除当前lpKeyName     如果lpKeyName=lpString=NULL,则删除当前Section以及其下的所有Key        如果Section或者Key不存在,则创建;存在则覆盖 返回:写入成功。   DWORD GetPrivateProfileSectionNames(   LPTSTR lpszReturnBuffer,             //存放所有Section的缓冲地址   DWORD nSize,                             //缓冲大小   LPCTSTR lpFileName                   //ini文件路径 ); 功能:得到ini文件中所有Section名。 返回:返回拷贝到缓冲中的字符个数。不包括结束符。 注意:返回的所有Section在缓冲中的存放格式为“Section1”,0,“Section2”,0。。。。       若需要得到具体的每个Section,则需要进行字符串解析。在后面的IniFile类中的GetAllKeysAndValues函数中会看到解       析步骤。 DWORD GetPrivateProfileSection(   LPCTSTR lpAppName,                   //节名,即Section       LPTSTR lpReturnedString,              //存放指定Section下所有的Key和KeyValue的缓冲地址   DWORD nSize,                              //缓冲大小   LPCTSTR lpFileName                     //ini文件路径 ); 功能:得到指定Section下所有的Key和KeyValue。 返回:返回拷贝到缓冲中的字符个数。不包括结束符。 注意:返回的“项-值对”在缓冲中的存放格式为“Key1=KeyValue1”,0,“Key2=KeyValue2”,0 。。。。 若需要得到具体的Key和KeyValue,则需要进行字符串解析。在后面的IniFile类中的GetAllKeysAndValues函数中会看到解析步骤。 GetPrivateProfileStruct和WritePrivateProfileStruct用的较少,本文也未介绍,感兴趣的朋友可以自己看看MSDN,里面也有详细介绍。     三.一个ini的类     有了以上的API后,我们就可以轻松的制作一个简单的操作ini文件的类了。   // // File: IniFile.h // Date: October 2004 // Author: lixiaosan // Email: airforcetwo@163.com // Copyright (c) 2004. All Rights Reserved. //   #if !defined(AFX_INIFILE_H__B5C0D7F7_8353_4C93_AAA4_38A688CA253C__INCLUDED_) #define AFX_INIFILE_H__B5C0D7F7_8353_4C93_AAA4_38A688CA253C__INCLUDED_   #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000   class CIniFile   { public:          CIniFile();          virtual ~CIniFile();            //    设置ini文件路径     //    成功返回TRUE;否则返回FALSE          BOOL         SetPath(CString strPath);                    //    检查section是否存在     //    存在返回TRUE;否则返回FALSE          BOOL         SectionExist(CString strSection);            //    从指定的Section和Key读取KeyValue         //    返回KeyValue          CString         GetKeyValue(CString    strSection,                                                         CString    strKey);                             //    设置Section、Key以及KeyValue,若Section或者Key不存在则创建          void          SetKeyValue(CString    strSection,                                                     CString    strKey,                                                     CString    strKeyValue);            //    删除指定Section下的一个Key          void          DeleteKey(CString strSection,                                                CString strKey);            //    删除指定的Section以及其下的所有Key          void          DeleteSection(CString strSection);            //    获得所有的Section         //    返回Section数目          int              GetAllSections(CStringArray& strArrSection);                    //    根据指定Section得到其下的所有Key和KeyValue         //    返回Key的数目          int              GetAllKeysAndValues(CString strSection,                                                                      CStringArray& strArrKey,                                                                      CStringArray& strArrKeyValue);            //       删除所有Section          void          DeleteAllSections();           private:          //       ini文件路径          CString m_strPath;             };   #endif // !defined(AFX_INIFILE_H__B5C0D7F7_8353_4C93_AAA4_38A688CA253C__INCLUDED_)       // // File: IniFile.cpp // Date: October 2004 // Author: lixiaosan // Email: airforcetwo@163.com // Copyright (c) 2004. All Rights Reserved. //   #include "stdafx.h" //#include "test6.h" #include "IniFile.h"     #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif   #define         MAX_SECTION                260        //Section最大长度 #define         MAX_KEY                         260        //KeyValues最大长度 #define         MAX_ALLSECTIONS     65535    //所有Section的最大长度 #define         MAX_ALLKEYS              65535    //所有KeyValue的最大长度 // // Construction/Destruction //   CIniFile::CIniFile() {   }   CIniFile::~CIniFile() {   }   // //   Public Functions //   BOOL CIniFile::SetPath(CString strPath) {          m_strPath = strPath;                    //       检查文件是否存在          DWORD  dwFlag = GetFileAttributes((LPCTSTR)m_strPath);                    //       文件或者路径不存在,返回FALSE          if( 0xFFFFFFFF == dwFlag )                    return FALSE;                    //       路径是目录,返回FALSE          if (  FILE_ATTRIBUTE_DIRECTORY & dwFlag )                    return FALSE;            return TRUE; }   BOOL CIniFile::SectionExist(CString strSection) {          TCHAR chSection[MAX_SECTION];          DWORD dwRetValue;            dwRetValue = GetPrivateProfileString(                   (LPCTSTR)strSection,                    NULL,                    _T(""),                   chSection,                   sizeof(chSection)/sizeof(TCHAR),                   (LPCTSTR)m_strPath);            return (dwRetValue>0); }   CString CIniFile::GetKeyValue(CString strSection,                                                           CString strKey) {          TCHAR         chKey[MAX_KEY];          DWORD         dwRetValue;          CString strKeyValue=_T("");            dwRetValue = GetPrivateProfileString(                   (LPCTSTR)strSection,                   (LPCTSTR)strKey,                    _T(""),                    chKey,                   sizeof(chKey)/sizeof(TCHAR),                   (LPCTSTR)m_strPath);                           strKeyValue = chKey;                    return strKeyValue;   }   void CIniFile::SetKeyValue(CString strSection,                                                  CString strKey,                                                  CString strKeyValue) {          WritePrivateProfileString(                   (LPCTSTR)strSection,                    (LPCTSTR)strKey,                    (LPCTSTR)strKeyValue,                    (LPCTSTR)m_strPath); }   void CIniFile::DeleteKey(CString strSection, CString strKey) {          WritePrivateProfileString(                   (LPCTSTR)strSection,                    (LPCTSTR)strKey,                     NULL,          //       这里写NULL,则删除Key                   (LPCTSTR)m_strPath); }   void CIniFile::DeleteSection(CString strSection) {          WritePrivateProfileString(                   (LPCTSTR)strSection,                     NULL,                              NULL,          //       这里都写NULL,则删除Section                   (LPCTSTR)m_strPath); }   int CIniFile::GetAllSections(CStringArray& strArrSection) {          int dwRetValue, i, j, iPos=0;          TCHAR chAllSections[MAX_ALLSECTIONS];          TCHAR chTempSection[MAX_SECTION];            ZeroMemory(chAllSections, MAX_ALLSECTIONS);          ZeroMemory(chTempSection, MAX_SECTION);            dwRetValue = GetPrivateProfileSectionNames(                   chAllSections,                   MAX_ALLSECTIONS,                   m_strPath);            //       因为Section在数组中的存放形式为“Section1”,0,“Section2”,0,0。     //       所以如果检测到连续两个0,则break          for(i=0; i<MAX_ALLSECTIONS; i++)           {                    if( chAllSections[i] == NULL )                     {                             if( chAllSections[i] == chAllSections[i+1] )                                      break;                     }          }                     i++; //         保证数据读完          strArrSection.RemoveAll(); //         清空数组                    for(j=0; j<i; j++)           {                    chTempSection[iPos++] = chAllSections[j];                    if( chAllSections[j] == NULL )                     {                               strArrSection.Add(chTempSection);                              ZeroMemory(chTempSection, MAX_SECTION);                             iPos = 0;                     }           }                    return strArrSection.GetSize(); }   int CIniFile::GetAllKeysAndValues(CString  strSection,                                                              CStringArray&         strArrKey,                                                              CStringArray& strArrKeyValue) {          int dwRetValue, i, j, iPos=0;          TCHAR chAllKeysAndValues[MAX_ALLKEYS];          TCHAR chTempkeyAndValue[MAX_KEY];          CString strTempKey;            ZeroMemory(chAllKeysAndValues, MAX_ALLKEYS);          ZeroMemory(chTempkeyAndValue, MAX_KEY);            dwRetValue = GetPrivateProfileSection(                   strSection,                   chAllKeysAndValues,                   MAX_ALLKEYS,                   m_strPath);            //       因为Section在数组中的存放形式为“Key1=KeyValue1”,0,“Key2=KeyValue2”,0          //       所以如果检测到连续两个0,则break          for(i=0; i<MAX_ALLSECTIONS; i++)           {                    if( chAllKeysAndValues[i] == NULL )                     {                             if( chAllKeysAndValues[i] == chAllKeysAndValues[i+1] )                                      break;                     }          }                     i++;          strArrKey.RemoveAll();          strArrKeyValue.RemoveAll();                    for(j=0; j<i; j++)           {                    chTempkeyAndValue[iPos++] = chAllKeysAndValues[j];                    if( chAllKeysAndValues[j] == NULL )                     {                               strTempKey = chTempkeyAndValue;                              strArrKey.Add( strTempKey.Left(strTempKey.Find('=')) );                             strArrKeyValue.Add( strTempKey.Mid(strTempKey.Find('=')+1) );                             ZeroMemory(chTempkeyAndValue, MAX_KEY);                             iPos = 0;                     }           }                    return strArrKey.GetSize(); }   void CIniFile::DeleteAllSections() {          int nSecNum;           CStringArray strArrSection;           nSecNum = GetAllSections(strArrSection);           for(int i=0; i<nSecNum; i++)           {                    WritePrivateProfileString(                             (LPCTSTR)strArrSection[i],                             NULL,                             NULL,                             (LPCTSTR)m_strPath);                 } }           四.例子 比如在存在一个myfile.ini文件,内容如下: [student] number=40 male=25 female=15 average_age=15   [computer] cpu=2.0 motherboard=ASUS harddisk=120 ram=512 display=sansung   现在把IniFile.h和IniFile.cpp 加入到你的工程中。在使用他的类中#include “IniFile.h”;            CIniFile file;          CStringArray arrSection, arrKey, arrkeyValue;          file.SetPath("f:\\ myfile.ini");          CString str="";            if(file.SectionExist("student"))          {                   //str="15"                    str = file.GetKeyValue("student", "female");                                        //设置number为50                   file.SetKeyValue("student", "number", "50");                      //因为在student中computer_num不存在,所以增加一项                   file.SetKeyValue("student", "computer_num", "30");                      //得到所有section                    int num = file.GetAllSections(arrSection);                    str = "";                    for(int i=0; i<num; i++)                    {                             str += arrSection[i] + " ";//str="student computer ";                    }                      //得到所有Key和KeyValue                    int num = file.GetAllKeysAndValues("computer", arrKey, arrkeyValue);                    str = "";                    for(int j=0; j<num; j++)                    {                             //arrKey保存了computer下所有的Key                             //arrkeyValue保存了computer下所有的KeyValue                             str = arrKey[j];                             str = arrkeyValue[j];                    }                    //删除student下的computer_num                   file.DeleteKey("student", "computer_num");                      //删除student                   file.DeleteSection("student");      }     有兴趣的朋友,可以在该类基础上进行扩展,添加你自己喜欢的功能。比如说返回int而不是字符串。

转载于:https://www.cnblogs.com/webman/archive/2007/10/11/921295.html

最新回复(0)