自制的一个读写INI文件的类

合集下载

VB读写INI文件

VB读写INI文件

VB读写INI文件今天,我们将应用制作一个能够实现读写INI文件的应用程序。

程序运行结果如图所示。

运行结果技术要点●INI文件的格式●GetPrivateProfileInt()和GetPrivateProfileString()函数●WritePrivateProfileString()函数实现步骤■新建项目打开Visual ,选择“新建项目”,在项目类型窗口中选择“Visual Basic项目”,在模板窗口中,选择“Windows应用程序”,在名称域中输入“RWIni”,然后选择保存路径。

单击“确认”。

■添加控件和菜单向当前窗体上添加两个Button控件,用于控制读写INI文件;一个Group控件和两个RadioButton控件,用于控制读写整型数据还是字符串型;三个Label控件和三个TextBox 控件,用于标注和输入节名、键名和值;其余两个Label控件,一个表示当前打开的文件名,另一个表示读写的状态。

最后添加一个MainMenu控件,生成菜单“文件”、“退出”,其中“文件”下有一个子菜单“打开INI文件”。

■设置属性切换到“属性栏”,对窗体上的控件设置属性。

详细情况见下表。

窗体各控件的属性值知识点:一个INI文件由若干节(Section)组成,每个节中又由若干个关键字(Keyword)和值组成。

关键字是用来保存独立的程序设置和那些重要信息的,用于控制应用程序的某个功能;值可以是整型数或字符串。

如果值为空,则表示应用程序已经为该关键字指定了缺省值。

INI文件的一般形式如下:…………[Section]keyword=value…………INI文件有严格的格式要求:(1)节名必须加“[”和“]”。

(2)对文件做注释,要以“;”开头。

(3)关键字后必须有“=”。

■添加代码keywordinfo = txtkeyword.TextValueinfo = txtvalue.Text' 检查输入是否合法,不合法时,提示警告信息。

C语言读取写入ini配置文件的方法实现

C语言读取写入ini配置文件的方法实现

C语⾔读取写⼊ini配置⽂件的⽅法实现⽬录⼀、了解什么是INI⽂件?⼆、INI⽂件的格式三、解析上述⽂件四、测试如下⼀、了解什么是INI⽂件?ini ⽂件是Initialization File的缩写,即初始化⽂件,这是⽤来配置应⽤软件以实现不同⽤户的要求。

⼆、INI⽂件的格式INI⽂件由节、键、值组成。

⼀个简单的的INI⽂件例⼦如下:[Setting]INIT_FLAG=0;VOLUME=1;LANGUAGE=1;如上例⼦,[Setting]就是节,=号左边的值是键,=号右边的是值。

三、解析上述⽂件/*ini.h*/#ifndef INI_H#define INI_H#include <stdio.h>#include <string.h>int GetIniKeyString(char *title,char *key,char *filename,char *buf);int PutIniKeyString(char *title,char *key,char *val,char *filename);#endif /*INI_H*//*ini.c*/#include <stdio.h>#include <string.h>/** 函数名: GetIniKeyString* ⼊⼝参数: title* 配置⽂件中⼀组数据的标识* key* 这组数据中要读出的值的标识* filename* 要读取的⽂件路径* 返回值:找到需要查的值则返回正确结果 0* 否则返回-1*/int GetIniKeyString(char *title,char *key,char *filename,char *buf){FILE *fp;int flag = 0;char sTitle[64], *wTmp;char sLine[1024];sprintf(sTitle, "[%s]", title);if(NULL == (fp = fopen(filename, "r"))) {perror("fopen");return -1;}while (NULL != fgets(sLine, 1024, fp)) {// 这是注释⾏if (0 == strncmp("//", sLine, 2)) continue;if ('#' == sLine[0]) continue;wTmp = strchr(sLine, '=');if ((NULL != wTmp) && (1 == flag)) {if (0 == strncmp(key, sLine, strlen(key))) { // 长度依⽂件读取的为准sLine[strlen(sLine) - 1] = '\0';fclose(fp);while(*(wTmp + 1) == ' '){wTmp++;}strcpy(buf,wTmp + 1);return 0;}} else {if (0 == strncmp(sTitle, sLine, strlen(sTitle))) { // 长度依⽂件读取的为准flag = 1; // 找到标题位置}}}fclose(fp);return -1;}/** 函数名: PutIniKeyString* ⼊⼝参数: title* 配置⽂件中⼀组数据的标识* key* 这组数据中要读出的值的标识* val* 更改后的值* filename* 要读取的⽂件路径* 返回值:成功返回 0* 否则返回 -1*/int PutIniKeyString(char *title,char *key,char *val,char *filename){FILE *fpr, *fpw;int flag = 0;char sLine[1024], sTitle[32], *wTmp;sprintf(sTitle, "[%s]", title);if (NULL == (fpr = fopen(filename, "r")))return -1;// 读取原⽂件sprintf(sLine, "%s.tmp", filename);if (NULL == (fpw = fopen(sLine, "w")))return -1;// 写⼊临时⽂件while (NULL != fgets(sLine, 1024, fpr)) {if (2 != flag) { // 如果找到要修改的那⼀⾏,则不会执⾏内部的操作wTmp = strchr(sLine, '=');if ((NULL != wTmp) && (1 == flag)) {if (0 == strncmp(key, sLine, strlen(key))) { // 长度依⽂件读取的为准flag = 2;// 更改值,⽅便写⼊⽂件sprintf(wTmp + 1, " %s\n", val);}} else {if (0 == strncmp(sTitle, sLine, strlen(sTitle))) { // 长度依⽂件读取的为准flag = 1; // 找到标题位置}}}fputs(sLine, fpw); // 写⼊临时⽂件}fclose(fpr);fclose(fpw);sprintf(sLine, "%s.tmp", filename);return rename(sLine, filename);// 将临时⽂件更新到原⽂件}上述两个函数是简单的解析函数,因为ini⽂件有很多种解析⽅式,根据不同的需求解析也不同所以要进⾏修改⽐如我的注释符号是 “ ;”,所以我需要修改并且根据实际功能需求也可以进⾏进⼀步的封装四、测试如下ini样本⽂件/*test.ini*/[city]beijing = hello-beijingshanghai = hello-shanghai#information[study]highschool = xxxxuniversity = yyyytest.c程序/*test.c*/#include "ini.h"#include <stdio.h>int main(int argc, char const *argv[]){char buff[100];int ret;ret = GetIniKeyString("city","beijing","./test.ini",buff);printf("ret:%d,%s\n",ret,buff);ret = GetIniKeyString("study","highschool","./test.ini",buff);printf("ret:%d,%s\n",ret,buff);ret = PutIniKeyString("study","highschool","zzzz","./test.ini");printf("put ret:%d\n",ret);ret = GetIniKeyString("study","highschool","./test.ini",buff);printf("ret:%d,%s\n",ret,buff);return 0;}结果如下:ret:0,hello-beijingret:0,xxxxput ret:0ret:0,zzzz相应的test.ini的study段highschool项变成了zzzz.这⾥还要注意,section使⽤中⽂字符可能会⽆法识别!到此这篇关于C语⾔读取写⼊ini配置⽂件的⽅法实现的⽂章就介绍到这了,更多相关C语⾔读取写⼊ini 内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。

c++中读取ini文件

c++中读取ini文件

在VC++中读写INI文件在VC++中读写INI文件在我们写的程序当中,总有一些配置信息需要保存下来,以便完成程序的功能,最简单的办法就是将这些信息写入INI文件中,程序初始化时再读入.具体应用如下:一.将信息写入.INI文件中.1.所用的WINAPI函数原型为:其中各参数的意义:LPCTSTR lpAppName 是INI文件中的一个字段名.LPCTSTR lpKeyName 是lpAppName下的一个键名,通俗讲就是变量名.LPCTSTR lpString 是键值,也就是变量的值,不过必须为LPCTSTR型或CString型的.LPCTSTR lpFileName 是完整的INI文件名.2.具体使用方法:设现有一名学生,需把他的姓名和年龄写入 c:\stud\student.ini 文件中.此时c:\stud\student.ini文件中的内容如下:[StudentInfo]Name=张三3.要将学生的年龄保存下来,只需将整型的值变为字符型即可:二.将信息从INI文件中读入程序中的变量.1.所用的WINAPI函数原型为:DWORD GetPrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpDefault,LPTSTR lpReturnedString,DWORD nSize,LPCTSTR lpFileName);其中各参数的意义:前二个参数与 WritePrivateProfileString中的意义一样.lpDefault : 如果INI文件中没有前两个参数指定的字段名或键名,则将此值赋给变量.lpReturnedString : 接收INI文件中的值的CString对象,即目的缓存器.nSize : 目的缓存器的大小.lpFileName : 是完整的INI文件名.2.具体使用方法:现要将上一步中写入的学生的信息读入程序中.执行后 strStudName 的值为:"张三",若前两个参数有误,其值为:"默认姓名".3.读入整型值要用另一个WINAPI函数:UINT GetPrivateProfileInt(LPCTSTR lpAppName,LPCTSTR lpKeyName,INT nDefault,LPCTSTR lpFileName);这里的参数意义与上相同.使用方法如下:三.循环写入多个值,设现有一程序,要将最近使用的几个文件名保存下来,具体程序如下:1.写入:CString strTemp,strTempA;int i;int nCount=6;file://共有6个文件名需要保存for(i=0;i {strTemp.Format("%d",i);strTempA=文件名;file://文件名可以从数组,列表框等处取得.::WritePrivateProfileString("UseFileName","FileName"+strTemp,strTempA,"c:\\usefile\\usefile.ini");}strTemp.Format("%d",nCount);::WritePrivateProfileString("FileCount","Count",strTemp,"c:\\usefile\\usefile.ini");file://将文件总数写入,以便读出.2.读出:nCount=::GetPrivateProfileInt("FileCount","Count",0,"c:\\usefile\\usefile.ini");for(i=0;i {strTemp.Format("%d",i);strTemp="FileName"+strTemp;::GetPrivateProfileString("CurrentIni",strTemp,"default.fil",strTempA.GetBuffer(MAX_PATH),MAX_PATH,"c:\\usefile\\usefile.ini");file://使用strTempA中的内容.}补充四点:1.INI文件的路径必须完整,文件名前面的各级目录必须存在,否则写入不成功,该函数返回 FALSE 值.2.文件名的路径中必须为 \\ ,因为在VC++中, \\ 才表示一个 \ .3.也可将INI文件放在程序所在目录,此时 lpFileName 参数为: ".\\student.ini".4.从网页中粘贴源代码时,最好先粘贴至记事本中,再往VC中粘贴,否则易造成编译错误,开始时我也十分不解,好好的代码怎么就不对呢?后来才找到这个方法.还有一些代码中使用了全角字符如:<,\等,也会造成编译错误.。

C语言读取INI配置文件

C语言读取INI配置文件

C语言读取INI配置文件Ini.h#pragma once#include"afxTempl.h"class DLLPORT CIni{private:CString m_strFileName;public:CIni(CString strFileName) :m_strFileName(strFileName){}public://一般性操作:BOOL SetFileName(LPCTSTR lpFileName); //设置文件名CString GetFileName(void); //获得文件名BOOL SetValue(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpValue, bool bCreate = true); //设置键值,bCreate是指段名及键名未存在时,是否创建。

CString GetValue(LPCTSTR lpSection, LPCTSTR lpKey); //得到键值.BOOL DelSection(LPCTSTR strSection); //删除段名BOOL DelKey(LPCTSTR lpSection, LPCTSTR lpKey); //删除键名public://高级操作:int GetSections(CStringArray& arrSection); //枚举出全部的段名int GetKeyValues(CStringArray& arrKey, CStringArray& arrValue, LPCTSTR lpSection); //枚举出一段内的全部键名及值BOOL DelAllSections();};/*使用方法:CIni ini("c:\\a.ini");int n;/*获得值TRACE("%s",ini.GetValue("段1","键1"));*//*添加值ini.SetValue("自定义段","键1","值");ini.SetValue("自定义段2","键1","值",false);*//*枚举全部段名CStringArray arrSection;n=ini.GetSections(arrSection);for(int i=0;i<n;i++)TRACE("%s\n",arrSection[i]);*//*枚举全部键名及值CStringArray arrKey,arrValue;n=ini.GetKeyValues(arrKey,arrValue,"段1");for(int i=0;i<n;i++)TRACE("键:%s\n值:%s\n",arrKey[i],arrValue[i]); *//*删除键值ini.DelKey("段1","键1");*//*删除段ini.DelSection("段1");*//*删除全部ini.DelAllSections();*/Ini.cpp#include"StdAfx.h"#include"Ini.h"#define MAX_ALLSECTIONS 2048 //全部的段名#define MAX_SECTION 260 //一个段名长度#define MAX_ALLKEYS 6000 //全部的键名#define MAX_KEY 260 //一个键名长度BOOL CIni::SetFileName(LPCTSTR lpFileName){CFile file;CFileStatus status;if (!file.GetStatus(lpFileName, status))return TRUE;m_strFileName = lpFileName;return FALSE;}CString CIni::GetFileName(void){return m_strFileName;}BOOL CIni::SetValue(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpValue, bool bCreate) {TCHAR lpTemp[MAX_PATH] = { 0 };//以下if语句表示如果设置bCreate为false时,当没有这个键名时则返回TRUE(表示出错)//!*&*none-value*&!* 这是个垃圾字符没有特别意义,这样乱写是防止凑巧相同。

ini文件的操作

ini文件的操作

delphi开发 ini文件使用详解:ini文件创建、打开、读取、写入操作。

ini文件常用作配置文件使用(1)INI文件的结构:[节点]关键字=值注:INI文件允许有多个节点,每个节点又允许有多个关键字,“=”后面是该关键字的值(类型有串、整型数值和布尔值。

其中字符串存贮在INI文件中时没有引号,布尔真值用1表示,布尔假值注释以分号“;”开头。

(2)INI文件的操作1、在Interface的Uses节增加IniFiles;2、在Var变量定义部分增加一行:inifile:Tinifile;然后,就可以对变量myinifile进行创建、写入等操作了。

procedureTForm1.FormCreate(Sender:TObject);varfilename:string;beginfilename:=ExtractFilePath(paramstr(0))+‘tmp.ini’;inifile:=TInifile.Create(filename);或filename:=getcurrentdir+ 'tmp.ini ';或inifile:=TInifile.Create(‘d:\tmp.ini’);3、打开INI文件:inifile:=Tinifile.create('tmp.ini'); //文件必须存在4、读取关键字的值:a:=inifile.Readstring('节点','关键字',缺省值);// string类型b:=inifile.Readinteger('节点','关键字',缺省值);// integer类型c:=inifile.Readbool('节点','关键字',缺省值);// boolean类型edit1.text:=inifile.Readstring('程序参数,'用户',‘’);checkbox1.checked:=inifile.Readbool('程序参数,'用户',checkbox1.checked);// boolean类型inifile.Readstring('程序参数,'用户',edit1.text);inifile.Readbool('程序参数,'用户',checkbox1.checked);其中[缺省值]为该INI文件不存在该关键字时返回的缺省值。

C++中ini文件读取类

C++中ini文件读取类

Ini文件读取类在.h文件中的定义以及相应函数声明。

class CIniFile : public CObject{private:CString m_AppPath; // The Path of Current ApplicationCStringArray m_SectionList; // The List of Section about INI Fileint m_iSectionLen;public:#define MAX_ALLSECTION_LEN 4096#define MAX_FNAME_LEN 260#define BufSize 16384CString m_iniFileName; // The Name of File about .INICIniFile(CString FileName);virtual ~CIniFile();void setFileName(CString FileName);boolean SectionExists(const CString& Section);//boolean ValueExists(const CString& Section,const CString Ident);// READvoid ReadSections();void ReadSection(const CString& Section,CStringArray &Strings);void ReadSectionValues(const CString& Section,CStringArray &Strings);CString ReadString(const CString& Section,const CString& Ident, const CString& Default);//CString ReadString(const CString Section,const CString Ident, const CString Default);int ReadInteger(const CString& Section,const CString& Ident, const int & Default);boolean ReadBool(const CString& Section,const CString& Ident, const boolean& Default);//WRITEvoid WriteString(const CString& Section,const CString& Ident,const CString& Value);void WriteInteger(const CString& Section,const CString& Ident,const int & Value);void WriteBool(const CString& Section,const CString& Ident,const boolean & Value);void EraseSection(CString Section);void DeleteKey(const CString& Section, const CString& Ident);void UpdateFile();CString GetMaxAllSectionLen();boolean FileExists();int FileAge(CString& FileName);};下面是cpp文件中的函数定义#include "stdafx.h"#include "IniFile.h"#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif//////////////////////////////////////////////////////////////////////// Construction/Destruction///////////////////////////////////////////////////////////////////////***************************** Example *************************** ** FileName = "\\Data\\HGG.ini";*/CIniFile::CIniFile(CString FileName){ASSERT(FileName);m_iniFileName = FileName;ReadSections();}CIniFile::~CIniFile(){UpdateFile();}boolean CIniFile::SectionExists(const CString& Section){ASSERT(m_SectionList.GetSize() > 0);//if (m_SectionList.GetSize() <= 0) return FALSE;for(int i =0;i<m_SectionList.GetSize();i++)if(m_SectionList[i] == Section){return TRUE;break;}return FALSE;}void CIniFile::setFileName(CString FileName){m_iniFileName = FileName;}// READvoid CIniFile::ReadSections(){ASSERT(m_iniFileName);TCHAR AllSection[MAX_ALLSECTION_LEN]={0};TCHAR SectionNames[MAX_FNAME_LEN]={0};DWORD retunValue;// The Result is same abount GetPrivateProfileSectionNames and GetPrivateProfileString //retunValue = GetPrivateProfileSectionNames(AllSection,MAX_ALLSECTION_LEN,m_iniFileName);retunValue = GetPrivateProfileString(NULL,NULL,NULL,AllSection,MAX_ALLSECTION_LEN,m_iniFileN ame);for(int i=0;i<MAX_ALLSECTION_LEN;i++){if(AllSection[i]==0)if(AllSection[i] == AllSection[i+1])break;}int k = 0;m_SectionList.RemoveAll();for(int j=0;j<i+1;j++){SectionNames[k++] = AllSection[j];if(AllSection[j] == NULL){m_SectionList.Add(SectionNames);memset(SectionNames,0,MAX_FNAME_LEN);k = 0;}}}void CIniFile::ReadSection(const CString& Section,CStringArray &Strings){TCHAR Buffer[BufSize]={0};TCHAR* pp=Buffer;CString str;Strings.RemoveAll();if (GetPrivateProfileString(Section, NULL, NULL, Buffer, BufSize,m_iniFileName) != NULL){while (*pp != NULL){Strings.Add(pp);pp += strlen(pp) + 1;}}}void CIniFile::ReadSectionV alues(const CString& Section,CStringArray &Strings){CStringArray KeyList;CString str;ReadSection(Section, KeyList);Strings.RemoveAll();for( int i=0; i<KeyList.GetSize();i++){str = KeyList.GetAt(i) + "=" + ReadString(Section,KeyList.GetAt(i),"");Strings.Add(str);};}CString CIniFile::ReadString(const CString& Section,const CString& Ident, const CString& Default){CString str;ASSERT(m_iniFileName);GetPrivateProfileString(Section,Ident, Default, str.GetBuffer(MAX_FNAME_LEN), MAX_FNAME_LEN, m_iniFileName);str.ReleaseBuffer();return str;}int CIniFile::ReadInteger(const CString& Section,const CString& Ident, const int & Default){CString str;int returnValue,safeSize;returnValue = Default;str = ReadString(Section, Ident, "");safeSize = str.GetLength();returnValue = atoi(str.GetBuffer(safeSize));str.ReleaseBuffer();/*#ifdef UNICODEWideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,str.GetBuffer(str.SafeStrlen())) atoi(str.GetData()->data());#elsereturnValue = atoi(str.GetData()->data());#endif*/return returnValue;}boolean CIniFile::ReadBool(const CString& Section,const CString& Ident, const boolean& Default){return (ReadInteger(Section, Ident,int(Default)) != 0);}//WRITEvoid CIniFile::WriteString(const CString& Section,const CString& Ident,const CString& Value) {WritePrivateProfileString(Section, Ident,Value,m_iniFileName);}void CIniFile::WriteInteger(const CString& Section,const CString& Ident,const int & Value){CString str;str.Format("%d",Value);WriteString(Section, Ident, str);}void CIniFile::WriteBool(const CString& Section,const CString& Ident,const boolean & Value) {CString Values[2] = {"0","1"};WriteString(Section, Ident, Values[Value]);}void CIniFile::EraseSection(CString Section){ASSERT(WritePrivateProfileString(Section, NULL, NULL, m_iniFileName));}void CIniFile::UpdateFile(){WritePrivateProfileString(NULL, NULL, NULL, m_iniFileName);}void CIniFile::DeleteKey(const CString& Section, const CString& Ident){WritePrivateProfileString(Section, Ident, NULL, m_iniFileName);}CString CIniFile::GetMaxAllSectionLen(){CString str;str.Format("%d",MAX_ALLSECTION_LEN);return str;}boolean CIniFile::FileExists(){ASSERT(m_iniFileName);return (FileAge(m_iniFileName) != -1);}int CIniFile::FileAge(CString& FileName){HANDLE Handle;WIN32_FIND_DA TA FindData;FILETIME LocalFileTime;WORD HiWord,LoWord;int resultValue;Handle = FindFirstFile(FileName, &FindData);if (Handle != INV ALID_HANDLE_V ALUE){FindClose(Handle);if ((FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0){FileTimeToLocalFileTime(&FindData.ftLastWriteTime, &LocalFileTime);if(FileTimeToDosDateTime(&LocalFileTime,&HiWord,&LoWord)){resultValue = HiWord;resultValue = resultValue << sizeof(HiWord)*8 | LoWord;return resultValue;}}}return (-1); }。

ini文件只知道节名,读取节下所有值的方法qt

ini文件只知道节名,读取节下所有值的方法qt

ini文件只知道节名,读取节下所有值的方法qt1.引言1.1 概述概述INI文件是一种常见的配置文件格式,它被广泛用于存储和管理应用程序的配置信息。

INI文件由一系列的节(section)和键值对(key-value)组成。

每个节包含一组相关的键值对,用来描述特定的配置项。

在读取INI 文件时,通常可以根据节名和键名来获取对应的值。

然而,在某些情况下,我们可能只知道节的名称,而不清楚该节下有哪些键值对。

本文将介绍如何通过Qt框架提供的方法来读取INI文件中某个节下的所有键值对。

首先,我们需要了解Qt框架中关于INI文件的相关类和函数。

Qt提供了一个名为QSettings的类,它是用于读写配置信息的工具类。

QSettings类支持INI文件格式,并提供了方便的方法来读取和写入INI 文件中的配置项。

在使用QSettings类读取INI文件时,我们可以先使用QSettings的构造函数来指定INI文件的路径,然后使用value()函数来获取指定节下的键值对。

为了读取某个节下的所有键值对,我们可以使用childGroups()函数来获取所有的子节名,然后再遍历每个子节获取其对应的键值对。

下面是一个简单的示例代码,展示了如何使用Qt框架中的QSettings 类来读取INI文件中某个节下的所有键值对:cppinclude <QSettings>include <QDebug>void readIniFile(const QString& filePath){QSettings settings(filePath, QSettings::IniFormat);QStringList sectionList = settings.childGroups();foreach (const QString& section, sectionList) {settings.beginGroup(section);QStringList keys = settings.childKeys();foreach (const QString& key, keys) {QString value = settings.value(key).toString();qDebug() << "Section:" << section << "Key:" << key << "Value:" << value;}settings.endGroup();}}int main(){QString filePath = "config.ini";readIniFile(filePath);return 0;}以上代码中,readIniFile()函数用于读取INI文件中某个节下的所有键值对。

ini文件编写方法

ini文件编写方法

ini文件编写方法一。

ini 文件是一种常见的配置文件格式,在很多软件和系统中都有广泛应用。

要编写一个好的 ini 文件,首先得搞清楚它的基本结构。

1.1 ini 文件通常由节(Section)和键值对(Key-Value Pair)组成。

节就像是一个个分类的文件夹,而键值对则是在这些文件夹里存放的具体信息。

比如说,[Settings] 这就是一个节的名称。

1.2 键值对呢,就是像“Key=Value”这样的形式。

比如说“FontSize=12”,“FontSize”是键,“12”就是值。

二。

在编写 ini 文件时,有一些要点得特别注意。

2.1 命名要清晰明了。

节名和键名都得让人一眼就能看出它是干啥的。

别整那些让人摸不着头脑的名字,不然回头自己都搞不清楚。

2.2 格式要规范。

每行一个键值对,别乱糟糟的,不然读起来就跟一团乱麻似的。

2.3 注释也很重要。

有时候给自己或者别人留个注释,说明一下这个键值是干啥用的,为啥这么设置,能省不少事儿。

三。

再来说说怎么修改和读取 ini 文件。

3.1 有很多编程语言都能处理 ini 文件。

比如说 Python 就有专门的库来读取和修改 ini 文件,用起来挺方便的。

3.2 但不管用啥方法,都得小心谨慎,别一不小心把重要的配置给改坏了,那可就麻烦大了。

编写 ini 文件虽然不算特别复杂,但也得用心去做,才能让它发挥应有的作用。

就像盖房子,基础打牢了,房子才能结实。

可别马马虎虎,不然到时候出了问题,就得返工,费时又费力!。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一个手工读写INI文件的类Windows中有GetPrivateProfileString 和WritePrivateProfileString函数可以进行读写INI 配置文件,但这两个函数每取出一个数据,都要打开文件,在文件中进行搜索,这样处理的效率肯定会很慢,因此下面提供了一个将配置文件读入内存中的做法,这样做的好处是一次读取文件,快速搜索(使用Map映射)。

可以将所有数据全部保存成字符串或者文件。

INI配置文件主要由四部分组成:组、键值、内容、注释和空行,下面给出一个例子文件进行说明文件:E:\boot.ini[boot loader] ;这里是一个组,下面的所有配置数据隶属于该组timeout=1 ;这里在等于好前面的是一个键值,等号后面的是一个内容default=multi(0)disk(0)rdisk(0)partition(2)\WINNT;下面一行是一个空行[operating systems];所有在';'后面的字符都属于注释,本程序不支持REM形式的注释multi(0)disk(0)rdisk(0)partition(2)\WINNT="Microsoft Windows 2000 Professional" /fastdetect;sadfkl;C:\="Microsoft Windows"好了,知道了INI文件的结构,开始分析INI文件读入内存后应使用的数据结构。

一个INI文件可以看作是由一些组以及每个组下面的数据组成的,组是字符串形式的,而数据是一个比较复杂的对象。

为了搜索的方便,所以这里采用了CMapStringToPtr来组织整个INI文件,这样的话可以由组的字符串方便地查询到该组中的数据一个组下面的数据是由一些键值— 内容组成的映射关系,所以使用CMapStringToString 来组这这些数据是最好不过的选择了。

下面给出这个类的头文件和实现部分。

给出之前简单介绍该类的用法:读取上述E:\boot.ini文件:#include "cfgdata.h"CCfgData CfgData;//Load INI文件CfgData.LoadCfgData("E:\\boot.ini");CString str;long l=0;//设置当前组CfgData.SetGroup("boot loader");//读取long型数据到变量lCfgData.GetLongData("timeout",l);//读取字符串型数据到变量strCfgData.GetStrData("default",str);//设置当前组CfgData.SetGroup("operating systems");//读取字符串型数据到变量strCfgData.GetStrData("multi(0)disk(0)rdisk(0)partition(2)\\WINNT",str);//读取字符串型数据到变量strCfgData.GetStrData("C:\\",str);//将整个配置数据保存进入字符串中CfgData.SaveToStr(&str);//将整个配置数据保存进入文件中,注意配置数据相互之间没有顺序关系,//所以可能组和组之间、一个组的几个键值--->内容配对之间的顺序将会//和以前不一致,另外所有的注释和空行丢失CfgData.SaveCfgData("E:\\boot2.ini");(读者可以点击这里获得源代码,注意解压后将boot.ini拷贝到E:\,以便程序运行找到文件)头文件CfgData.h// CfgData.h: interface for the CCfgData class.////////////////////////////////////////////////////////////////////////#if !defined(AFX_CFGDATA_H__A40CDB9A_0E44_49E6_A460_505D76BA6414__INCLUDED_) #define AFX_CFGDATA_H__A40CDB9A_0E44_49E6_A460_505D76BA6414__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class CCfgData{protected://组到配置数据的映射CMapStringToPtr m_StrMapMap;//当前组CString m_strGroup;public://构造配置数据CCfgData();//析构配置数据virtual ~CCfgData();//从文件加载配置数据/*参数:LPCTSTR strFileName 加载文件的名称返回值:无*/void LoadCfgData(LPCTSTR strFileName);//将配置数据保存到文件/*参数:LPCTSTR strFileName 保存文件的名称返回值:成功返回TRUE 失败返回FALSE*/BOOL SaveCfgData(LPCTSTR strFileName);//将配置数据保存到字符串/*参数:CString* pstr 要保存的字符串指针返回值:成功返回TRUE 失败返回FALSE*/BOOL SaveToStr(CString* pstr);//设置当前读取的组/*参数:当前组名称返回值:无*/void SetGroup(LPCTSTR strGroup);//修改或者添加一条当前组中的数据/*参数:LPCTSTR strKey 要修改的数据的键值LPCTSTR strValue要修改的数据的内容返回值:备注:如果当前组在配置数据中存在,则修改或者添加该组对应键值的数据,如果当前组灾配置数据中不存在,则先创建该组*/BOOL SetData(LPCTSTR strKey,LPCTSTR strValue);//得到当前组中对应键值中字符串类型的数据/*参数:LPCTSTR strKey 要得到的数据的键值LPCTSTR strValue要得到的数据的内容返回值:找到数据返回TRUE,否则返回FALSE*/virtual BOOL GetStrData(LPCTSTR strKey,CString &strValue);//得到long型的数据/*参数:LPCTSTR strKey 要得到的数据的键值long lValue 要得到的数据的值返回值:找到数据返回TRUE,否则返回FALSE*/virtual BOOL GetLongData(LPCTSTR strKey,long &lValue);protected://释放配置数据所占用的内存/*参数:无返回值:无*/void RemoveAll();};#endif// !defined(AFX_CFGDATA_H__A40CDB9A_0E44_49E6_A460_505D76BA6414__INCLUDED_)源文件CfgData.cpp// CfgData.cpp: implementation of the CCfgData class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "CfgData.h"#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif//////////////////////////////////////////////////////////////////////// Construction/Destruction////////////////////////////////////////////////////////////////////////构造配置数据CCfgData::CCfgData(){//初始化配置数据m_strGroup="设置";}//析构配置数据CCfgData::~CCfgData(){RemoveAll();}//释放配置数据所占用的内存/*参数:无返回值:无*/void CCfgData::RemoveAll(){POSITION pos=m_StrMapMap.GetStartPosition();while(pos){CMapStringToString* pStrMap;CString str;m_StrMapMap.GetNextAssoc(pos,str,(void*&)pStrMap);if(pStrMap!=NULL){pStrMap->RemoveAll();//删除掉CString--> 指针映射中的指针delete pStrMap;}}m_StrMapMap.RemoveAll();}//从文件加载配置数据/*参数:LPCTSTR strFileName 加载文件的名称返回值:无*/void CCfgData::LoadCfgData(LPCTSTR strFileName){int iReadLen=0;CString str[3];int iState=0;//0:正在读入键值1:正在读入内容2:正在读入组unsigned char ch; //正在读取的字符//清空配置数据RemoveAll();CFile file;file.Open(strFileName, CFile::modeRead);file.Seek(0,CFile::begin);str[0]="";//存放键值字符串str[1]="";//存放内容字符串str[2]="";//存放组字符串//字符串到字符串的映射,保存键值和内容CMapStringToString* pStrMap=NULL;do{iReadLen=file.Read(&ch,1);if(iReadLen!=0){//处理中文if(ch>0x80)//中文{str[iState]+=ch;iReadLen=file.Read(&ch,1);if(iReadLen!=0){str[iState]+=ch;}}else{switch(ch){//处理'['读入组字符串case'[':str[0].TrimLeft();str[0].TrimRight();str[1].TrimLeft();str[1].TrimRight();//确认键值和内容数据为空,否则可能是键值和内容中的符号if(str[0]==""&&str[1]==""){pStrMap=NULL;iState=2;str[2]="";}else{str[iState]+=ch;}break;//处理']'组字符串读入完毕case']'://确认读入的是组的字符串数据str[2].TrimLeft();str[2].TrimRight();if(iState==2&&str[2]!=""){iState=0;//新建一个组下的键值-->内容映射,放入该组pStrMap=new CMapStringToString;m_StrMapMap.SetAt(str[2],pStrMap);}else{str[iState]+=ch;}break;case'='://开始读入内容iState=1;str[1]="";break;//处理回车和注释case';':case 0x0d:case 0x0a:iState=0;//键值非空str[0].TrimLeft();str[0].TrimRight();str[1].TrimLeft();str[1].TrimRight();if(str[0]!=""&&pStrMap!=NULL){pStrMap->SetAt((LPCTSTR)str[0],(LPCTSTR)str[1]);}//处理完清空数据str[0]="";str[1]="";//注释的话继续读入直到文件结束或者碰到回车符号if(ch==';'){while((iReadLen=file.Read(&ch,1))>0){//如果遇到回车符号,终止,并且将当前位置退回if(ch==0x0d||ch==0x0a){file.Seek(-1,CFile::current);break;}}}break;default://普通字符,添加进入相应位置str[iState]+=ch;break;}}}}while(iReadLen!=0);file.Close();}//设置当前读取的组/*参数:当前组名称返回值:无*/void CCfgData::SetGroup(LPCTSTR strGroup){m_strGroup=strGroup;}//得到当前组中对应键值中字符串类型的数据/*参数:LPCTSTR strKey 要得到的数据的键值LPCTSTR strValue要得到的数据的内容返回值:找到数据返回TRUE,否则返回FALSE*/BOOL CCfgData::GetStrData(LPCTSTR strKey, CString &strValue) {CMapStringToString* pStrMap=NULL;//寻找当前组if(m_StrMapMap.Lookup(m_strGroup,(void*&)pStrMap)){if(pStrMap->Lookup(strKey,strValue))return TRUE;}return FALSE;}//得到long型的数据/*参数:LPCTSTR strKey 要得到的数据的键值long lValue 要得到的数据的值返回值:找到数据返回TRUE,否则返回FALSE*/BOOL CCfgData::GetLongData(LPCTSTR strKey, long &lValue){CString str;//得到对应的字符串数据if(CCfgData::GetStrData(strKey, str)){lValue=atoi((LPCTSTR)str);return TRUE;}return FALSE;}//修改或者添加一条当前组中的数据/*参数:LPCTSTR strKey 要修改的数据的键值LPCTSTR strValue要修改的数据的内容返回值:备注:如果当前组在配置数据中存在,则修改或者添加该组对应键值的数据,如果当前组灾配置数据中不存在,则先创建该组*/BOOL CCfgData::SetData(LPCTSTR strKey, LPCTSTR strValue){CMapStringToString* pStrMap=NULL;//如果存在该组,直接加入或者修改if(m_StrMapMap.Lookup(m_strGroup,(void*&)pStrMap)){pStrMap->SetAt(strKey,strValue);return TRUE;}else{//创建该组pStrMap=new CMapStringToString;m_StrMapMap.SetAt(m_strGroup,pStrMap);pStrMap->SetAt(strKey,strValue);}}//将配置数据保存到文件/*参数:LPCTSTR strFileName 保存文件的名称返回值:成功返回TRUE 失败返回FALSE*/BOOL CCfgData::SaveCfgData(LPCTSTR strFileName){CFile file;if(!file.Open(strFileName,CFile::modeCreate|CFile::modeWrite)) return FALSE;POSITION pos=m_StrMapMap.GetStartPosition();char ch[6]="[]\r\n=";//特殊符号CString str[3];while(pos){CMapStringToString* pStrMap;m_StrMapMap.GetNextAssoc(pos,str[2],(void*&)pStrMap);if(pStrMap!=NULL){//写入组file.Write(&ch[0],1);file.Write((LPSTR)(LPCTSTR)str[2],str[2].GetLength());file.Write(&ch[1],1);file.Write(&ch[2],2);POSITION pos1=pStrMap->GetStartPosition();while(pos1){//写入键值和内容pStrMap->GetNextAssoc(pos1,str[0],str[1]);file.Write((LPSTR)(LPCTSTR)str[0],str[0].GetLength());file.Write(&ch[4],1);file.Write((LPSTR)(LPCTSTR)str[1],str[1].GetLength());file.Write(&ch[2],2);}}}file.Close();return TRUE;}//将配置数据保存到字符串/*参数:CString* pstr 要保存的字符串指针返回值:成功返回TRUE 失败返回FALSE备注:程序流程和上面基本相同,不同的保存进入字符串中*/BOOL CCfgData::SaveToStr(CString *pstr){if(pstr==NULL)return FALSE;*pstr="";POSITION pos=m_StrMapMap.GetStartPosition();CString str[4];while(pos){CMapStringToString* pStrMap;m_StrMapMap.GetNextAssoc(pos,str[2],(void*&)pStrMap);if(pStrMap!=NULL){str[3]=*pstr;pstr->Format("%s[%s]\r\n",str[3],str[2]);POSITION pos1=pStrMap->GetStartPosition();while(pos1){pStrMap->GetNextAssoc(pos1,str[0],str[1]);str[3]=*pstr;pstr->Format("%s%s=%s\r\n",str[3],str[0],str[1]);}}}return TRUE;}。

相关文档
最新文档