ini文件的操作

来源:互联网 发布:成都真那么好么知乎 编辑:程序博客网 时间:2024/05/17 21:58

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

前言:

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

}

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孕期老公不知道关心不体贴怎么办? 中国和伊朗做贸易美国制裁怎么办 土地被村民霸占村长解决不了怎么办 村支书霸占群众选举村长的票怎么办 苹果手机自带的音乐软件删了怎么办 不小心把手机系统软件删了怎么办 佳能打印机打相片是打不全怎么办 卖家说我寄回去的包是假的怎么办 辞职后原单位没把档案给转出怎么办 天下行以租代购要起诉我怎么办 顺丰收件人电话地址都写错了怎么办 领导问任务完不成怎么办怎么回答 我和我老婆感情出现问题了怎么办 手机坏了手机浏览器里照片怎么办 不小心把电脑ie浏览器删了怎么办 华为手机自带浏览器中病毒了怎么办 手机打开浏览器提示中病毒了怎么办 手机卸载了浏览器和软件商店怎么办 房东在我租房期间贴房子出租怎么办 额头上毛孔大 还有些黑怎么办 孩子学跳舞老师压的疼怎么办 步步高点读机电池坏了怎么办 电脑连接受限制或无连接怎么办 电脑无线网受限制或无连接怎么办 电脑网络受限制或无连接怎么办 3 证书报考大专证书丢了怎么办 广工期末考试被老师警告了怎么办 我在农村不当队长我能力不够怎么办 我在农村不当队长我当代表怎么办 北京本地人社保中间断了一年怎么办 我想把大哥的孩子带出国要怎么办 美国有亲戚想让孩子出国怎么办 连接温控器的线断了怎么办 植发后好多原生发都脱落了怎么办 4岁宝宝支体能力差怎么办 当与游客发生矛盾时员工怎么办 顾客与同事发生矛盾你该怎么办 当一个人犯下的过错难以原谅怎么办 开车把别人撞成植物人了该怎么办 结婚证丢了孩子上不上学了怎么办 办房产证前加户主姓名怎么办手续