作者:lixiaosan(优快云)
前言: 相信很多朋友在编写自己的程序中,都需要把一些数据先期导入到程序中进行初始化。那么这个时候,比较好的做法就是把你所有的数据写入一个ini文件,然后在程序去读ini文件中的数据对行初始化。
一.INI简介那么什么是ini文件呢?ini文件是Initialization file的缩写,意即初始化文件。(从名字就可以看出它的功能了吧)。不仅你自己的程序可以使用ini文件,其实windows操作系统也有自己的ini文件---win.ini,保存在%WinDir%/system32目录下。Windows通过该文件对当前操作系统进行配置。 ini文件里的数据的存取是采取的是预先约定好的 “项-值”存储结构,各种数据被分门别类的存储。以下是win.ini 文件的部分内容。
通过以上内容,我们可以看到,ini文件将各种数据分成很多以“[ ]”组成的节,而在每一个“节”中又包含了很多“项”,“项”后面紧跟着一个等号,等号后面则是该项的值。在该例中[Mail]就是一个“节”,MAPI是一个项,1则是MAPI的值。 [Section] Key=KeyValue
二.操作ini文件的APIwindows SDK提供有两组API对ini文件进行读写。
表2
表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 INT nDefault, //缺省返回整型值。如lpKeyName未找到,函数返回nDefault的值 LPCTSTR lpFileName //ini文件路径 ); 功能:根据指定的Section和 Key得到整型KeyValue 返回:返回得到的整型KeyValue
BOOL WritePrivateProfileString( LPCTSTR lpAppName, //节名,即Section LPCTSTR lpString, //要写入的字符串 LPCTSTR lpFileName //ini文件路径 功能:向指定的Section和 Key写入KeyValue。 如果lpKeyName=lpString=NULL,则删除当前Section以及其下的所有Key 如果Section或者Key不存在,则创建;存在则覆盖 DWORD GetPrivateProfileSectionNames( LPTSTR lpszReturnBuffer, //存放所有Section的缓冲地址 DWORD nSize, //缓冲大小 LPCTSTR lpFileName //ini文件路径 ); 功能:得到ini文件中所有Section名。 返回:返回拷贝到缓冲中的字符个数。不包括结束符。 若需要得到具体的每个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函数中会看到解析步骤。
三.一个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文件路径 BOOL SetPath(CString strPath);
// 检查section是否存在 BOOL SectionExist(CString strSection);
// 从指定的Section和Key读取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 int GetAllSections(CStringArray& strArrSection);
// 根据指定Section得到其下的所有Key和KeyValue 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。 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 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"); }
返回:写入成功。 |
轻松实现一个操作ini文件的类
最新推荐文章于 2022-01-17 18:59:26 发布