首    页 界面/窗口 网络/通讯 数据库 组件开发 图像/多媒体 NET/Web 其它技术 源码下载 资料下载 软件共享 软件外包 曲艺杂谈
栏目导航:  首    页  |  其它技术  |  文件/系统 


轻松实现一个操作ini文件的类


原作者:lixiaosan    源出处:CSDN    发布者:施昌权    发布类型:转载    发布日期:2008-09-12

             

        前言:

        相信很多朋友在编写自己的程序中,都需要把一些数据先期导入到程序中进行初始化。那么这个时候,比较好的做法就是把你所有的数据写入一个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 lpAppNameLPCTSTR lpKeyName,           //项名,即Key,          //节名,即Section

                INT nDefault,                           //缺省返回整型值。如lpKeyName未找到,函数返回nDefault的值

                LPCTSTR lpFileName             //ini文件路径

        );

        功能:根据指定的Section和 Key得到整型KeyValue

        返回:返回得到的整型KeyValue 

        BOOL WritePrivateProfileString(

                        LPCTSTR lpAppNameLPCTSTR lpKeyName,           //项名,即Key,           //节名,即Section

                        LPCTSTR lpString,                  //要写入的字符串

                        LPCTSTR lpFileName             //ini文件路径

        功能:向指定的Section和 Key写入KeyValue。
        如果lpString为NULL,则删除当前lpKeyName

        如果lpKeyName=lpString,则删除当前Section以及其下的所有Key=NULL

        如果Section或者Key不存在,则创建;存在则覆盖

        返回:写入成功。

        DWORD GetPrivateProfileSectionNames(

                        LPTSTR lpszReturnBuffer,             //存放所有Section的缓冲地址

                        DWORD

                        nSize

        功能:得到ini文件中所有Section名。

        返回:返回拷贝到缓冲中的字符个数。不包括结束符。

        若需要得到具体的每个Section,则需要进行字符串解析。在后面的IniFile类中的GetAllKeysAndValues函数中会看到解析步骤。

        DWORD GetPrivateProfileSection(

                        LPCTSTR lpAppName节名,即Section    ,                   //

                        LPTSTR lpReturnedString存放指定Section下所有的Key和KeyValue的缓冲地址,              //

                        DWORD nSize缓冲大小,                              //

                        LPCTSTR lpFileName文件路径和WritePrivateProfileStruct用的较少,本文也未介绍,感兴趣的朋友可以自己看看MSDN,里面也有详细介绍。                  

        );

        功能:得到指定Section下所有的Key和KeyValue。

        返回:返回拷贝到缓冲中的字符个数。不包括结束符。

        注意:返回的“项-值对”在缓冲中的存放格式为“Key1=KeyValue1”,0,“Key2=KeyValue2”,0 。。。。

        若需要得到具体的Key和KeyValue,则需要进行字符串解析。在后面的IniFile类中的GetAllKeysAndValues函数中会看到解析步骤。

        GetPrivateProfileStruct

        三.一个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 

        classCIniFile 

        {

        public:

                CIniFile();

                virtual ~CIniFile(); 

                //    设置ini文件路径
                //    成功返回TRUE;否则返回FALSE

                BOOL         SetPath(CStringstrPath);        

                //    检查section是否存在
                //    存在返回TRUE;否则返回FALSE

                BOOL         SectionExist(CStringstrSection); 

                //    从指定的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(CStringstrSection,

                                CStringstrKey);

 

                //    删除指定的Section以及其下的所有Key

                void         DeleteSection(CStringstrSection); 

                //    获得所有的Section
                //    返回Section数目

                int              GetAllSections(CStringArray& strArrSection);        

                //    根据指定Section得到其下的所有Key和KeyValue
                //    返回Key的数目

                int              GetAllKeysAndValues(CStringstrSection,

                                                CStringArray& strArrKey,

                                                CStringArray& strArrKeyValue); 

                //       删除所有Section

                void         DeleteAllSections();        

        private:

                //       ini文件路径

                CStringm_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

        staticcharTHIS_FILE[]=__FILE__;

        #define newDEBUG_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

        ////////////////////////////////////////////////////////////////////////// 

        BOOLCIniFile::SetPath(CStringstrPath)

        {

                m_strPath = strPath;        

                //       检查文件是否存在

                DWORD dwFlag = GetFileAttributes((LPCTSTR)m_strPath);        

                //       文件或者路径不存在,返回FALSE

                if( 0xFFFFFFFF == dwFlag )

                        returnFALSE;        

                //       路径是目录,返回FALSE

                if ( FILE_ATTRIBUTE_DIRECTORY & dwFlag )

                        returnFALSE; 

                returnTRUE;

        } 

        BOOLCIniFile::SectionExist(CStringstrSection)

        {

                TCHARchSection[MAX_SECTION];

                DWORDdwRetValue; 

                dwRetValue = GetPrivateProfileString(

                        (LPCTSTR)strSection,

                        NULL,

                        _T(""),

                        chSection,

                        sizeof(chSection)/sizeof(TCHAR),

                        (LPCTSTR)m_strPath); 

                        return (dwRetValue>0);

        } 

        CStringCIniFile::GetKeyValue(CStringstrSection,

                        CStringstrKey)

        {

                TCHAR         chKey[MAX_KEY];

                DWORD         dwRetValue;

                CStringstrKeyValue=_T(""); 

                dwRetValue = GetPrivateProfileString(

                        (LPCTSTR)strSection,

                        (LPCTSTR)strKey,

                        _T(""),

                        chKey,

                        sizeof(chKey)/sizeof(TCHAR),

                        (LPCTSTR)m_strPath);              

                        strKeyValue = chKey;        

                        returnstrKeyValue; 

        } 

        voidCIniFile::SetKeyValue(CStringstrSection,

                                        CStringstrKey,

                                        CStringstrKeyValue)

        {

                WritePrivateProfileString(

                                (LPCTSTR)strSection,

                                (LPCTSTR)strKey,

                                (LPCTSTR)strKeyValue,

                                (LPCTSTR)m_strPath);

        } 

        voidCIniFile::DeleteKey(CStringstrSection, CStringstrKey)

        {

                WritePrivateProfileString(

                                (LPCTSTR)strSection,

                                (LPCTSTR)strKey,

                                NULL,          //       这里写NULL,则删除Key

                                (LPCTSTR)m_strPath);

        } 

        voidCIniFile::DeleteSection(CStringstrSection)

        {

                WritePrivateProfileString(

                        (LPCTSTR)strSection,

                        NULL,         

                        NULL,          //       这里都写NULL,则删除Section

                        (LPCTSTR)m_strPath);

        } 

        intCIniFile::GetAllSections(CStringArray& strArrSection)

        {

                intdwRetValue, i, j, iPos=0;

                TCHARchAllSections[MAX_ALLSECTIONS];

                TCHARchTempSection[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;

                        }

                }        

                returnstrArrSection.GetSize();

        } 

        intCIniFile::GetAllKeysAndValues(CString strSection,

                CStringArray&         strArrKey,

                CStringArray& strArrKeyValue)

        {

                intdwRetValue, i, j, iPos=0;

                TCHARchAllKeysAndValues[MAX_ALLKEYS];

                TCHARchTempkeyAndValue[MAX_KEY];

                CStringstrTempKey; 

                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;

                        }

                }        

                returnstrArrKey.GetSize();

        } 

        voidCIniFile::DeleteAllSections()

        {

         intnSecNum;

                CStringArraystrArrSection;

                nSecNum = GetAllSections(strArrSection);

                for(inti=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”;

        CIniFilefile;

        CStringArrayarrSection, arrKey, arrkeyValue;

        file.SetPath("f:""myfile.ini");

        CStringstr="";

 

        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

                intnum = file.GetAllSections(arrSection);

                str = "";

                for(inti=0; i<num; i++)

                {

                        str += arrSection[i] + " ";//str="student computer ";

                }

 

                //得到所有Key和KeyValue

                intnum = file.GetAllKeysAndValues("computer", arrKey, arrkeyValue);

                str = "";

                for(intj=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而不是字符串。
        就讲到这里吧,欢迎大家指正。:) 

        注意:返回的所有Section在缓冲中的存放格式为“Section1”,0,“Section2”,0。。。。,                             //缓冲大小

        LPCTSTR lpFileName                   //ini文件路径 

                              
关于我们 版权声明 广告服务 联系我们 友情链接 加入收藏
站长:施昌权    Email:scq2099yt@163.com    MSN:scq2099yt@live.cn    QQ:14046300    本站QQ群:67202409
Copyright © 2008     卓为VC(www.joyvc.cn)    All Rights Reserved    建议分辨率 1024×768
本站由施昌权制作维护
京ICP备09012297号