您的位置:首页 > 编程语言 > C语言/C++

用Visual_C++操作INI文件.doc

2012-03-17 20:28 309 查看
在我们写的程序当中,总有一些配置信息需要保存下来,以便完成程序的功能,最简单的办法就是将这些信息写入INI文件中,程序初始化时再读入.具体应用如下:

  一.将信息写入.INI文件中.

  1.所用的WINAPI函数原型为:

BOOL WritePrivateProfileString(

LPCTSTR lpAppName,

LPCTSTR lpKeyName,

LPCTSTR lpString,

LPCTSTR lpFileName

);

  其中各参数的意义:

   LPCTSTR lpAppName 是INI文件中的一个字段名.

   LPCTSTR lpKeyName 是lpAppName下的一个键名,通俗讲就是变量名.

   LPCTSTR lpString 是键值,也就是变量的值,不过必须为LPCTSTR型或CString型的.

   LPCTSTR lpFileName 是完整的INI文件名.

  2.具体使用方法:设现有一名学生,需把他的姓名和年龄写入 c:\stud\student.ini 文件中.

CString strName,strTemp;

int nAge;

strName="张三";

nAge=12;

::WritePrivateProfileString("StudentInfo","Name",strName,"c:\\stud\\student.ini");

  此时c:\stud\student.ini文件中的内容如下:

   [StudentInfo]

   Name=张三

  3.要将学生的年龄保存下来,只需将整型的值变为字符型即可:

strTemp.Format("%d",nAge);

::WritePrivateProfileString("StudentInfo","Age",strTemp,"c:\\stud\\student.ini");

 二.将信息从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.具体使用方法:现要将上一步中写入的学生的信息读入程序中.

CString strStudName;

int nStudAge;

GetPrivateProfileString("StudentInfo","Name","默认姓名",strStudName.GetBuffer(MAX_PATH),MAX_PATH,"c:\\stud\\student.ini");

  执行后 strStudName 的值为:"张三",若前两个参数有误,其值为:"默认姓名".

  3.读入整型值要用另一个WINAPI函数:

UINT GetPrivateProfileInt(

LPCTSTR lpAppName,

LPCTSTR lpKeyName,

INT nDefault,

LPCTSTR lpFileName

);

  这里的参数意义与上相同.使用方法如下:

nStudAge=GetPrivateProfileInt("StudentInfo","Age",10,"c:\\stud\\student.ini");

三.循环写入多个值,设现有一程序,要将最近使用的几个文件名保存下来,具体程序如下:

  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".

//----------------------------------------------------------------------------------

/*

类名:CIni

版本:v2.0

最后更新:

v2.0

梦小孩于2004年2月14日情人节

加入高级操作的功能

v1.0

梦小孩于2003年某日

一般操作完成

类描述:

本类可以于.ini文件进行操作

*/

文件 1:

#pragma once

#include "afxTempl.h"

class 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();

};

文件 2:

#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*&!* 这是个垃圾字符没有特别意义,这样乱写是防止凑巧相同。

if (!bCreate)

{

GetPrivateProfileString(lpSection,lpKey,"!*&*none-value*&!*",lpTemp,MAX_PATH,m_strFileName);

if(strcmp(lpTemp,"!*&*none-value*&!*")==0)

return TRUE;

}

if(WritePrivateProfileString(lpSection,lpKey,lpValue,m_strFileName))

return FALSE;

else

return GetLastError();

}

CString CIni::GetValue(LPCTSTR lpSection, LPCTSTR lpKey)

{

DWORD dValue;

TCHAR lpValue[MAX_PATH] ={0};

dValue=GetPrivateProfileString(lpSection,lpKey,"",lpValue,MAX_PATH,m_strFileName);

return lpValue;

}

BOOL CIni::DelSection(LPCTSTR lpSection)

{

if(WritePrivateProfileString(lpSection,NULL,NULL,m_strFileName))

return FALSE;

else

return GetLastError();

}

BOOL CIni::DelKey(LPCTSTR lpSection, LPCTSTR lpKey)

{

if(WritePrivateProfileString(lpSection,lpKey,NULL,m_strFileName))

return FALSE;

else

return GetLastError();

}

int CIni::GetSections(CStringArray& arrSection)

{

/*

本函数基础:

GetPrivateProfileSectionNames - 从 ini 文件中获得 Section 的名称

如果 ini 中有两个 Section: [sec1] 和 [sec2],则返回的是 'sec1',0,'sec2',0,0 ,当你不知道

ini 中有哪些 section 的时候可以用这个 api 来获取名称

*/

int i;

int iPos=0;

int iMaxCount;

TCHAR chSectionNames[MAX_ALLSECTIONS]={0}; //总的提出来的字符串

TCHAR chSection[MAX_SECTION]={0}; //存放一个段名。

GetPrivateProfileSectionNames(chSectionNames,MAX_ALLSECTIONS,m_strFileName);

//以下循环,截断到两个连续的0

for(i=0;i<MAX_ALLSECTIONS;i++)

{

if (chSectionNames[i]==0)

if (chSectionNames[i]==chSectionNames[i+1])

break;

}

iMaxCount=i+1; //要多一个0号元素。即找出全部字符串的结束部分。

arrSection.RemoveAll();//清空原数组

for(i=0;i<iMaxCount;i++)

{

chSection[iPos++]=chSectionNames[i];

if(chSectionNames[i]==0)

{

arrSection.Add(chSection);

memset(chSection,0,MAX_SECTION);

iPos=0;

}

}

return (int)arrSection.GetSize();

}

int CIni::GetKeyValues(CStringArray& arrKey,CStringArray& arrValue, LPCTSTR lpSection)

{

/*

本函数基础:

GetPrivateProfileSection- 从 ini 文件中获得一个Section的全部键名及值名

如果ini中有一个段,其下有 "段1=值1" "段2=值2",则返回的是 '段1=值1',0,'段2=值2',0,0 ,当你不知道

获得一个段中的所有键及值可以用这个。

*/

int i;

int iPos=0;

CString strKeyValue;

int iMaxCount;

TCHAR chKeyNames[MAX_ALLKEYS]={0}; //总的提出来的字符串

TCHAR chKey[MAX_KEY]={0}; //提出来的一个键名

GetPrivateProfileSection(lpSection,chKeyNames,MAX_ALLKEYS,m_strFileName);

for(i=0;i<MAX_ALLKEYS;i++)

{

if (chKeyNames[i]==0)

if (chKeyNames[i]==chKeyNames[i+1])

break;

}

iMaxCount=i+1; //要多一个0号元素。即找出全部字符串的结束部分。

arrKey.RemoveAll();//清空原数组

arrValue.RemoveAll();

for(i=0;i<iMaxCount;i++)

{

chKey[iPos++]=chKeyNames[i];

if(chKeyNames[i]==0)

{

strKeyValue=chKey;

arrKey.Add(strKeyValue.Left(strKeyValue.Find("=")));

arrValue.Add(strKeyValue.Mid(strKeyValue.Find("=")+1));

memset(chKey,0,MAX_KEY);

iPos=0;

}

}

return (int)arrKey.GetSize();

}

BOOL CIni::DelAllSections()

{

int nSection;

CStringArray arrSection;

nSection=GetSections(arrSection);

for(int i=0;i<nSection;i++)

{

if(DelSection(arrSection[i]))

return GetLastError();

}

return FALSE;

}

使用方法:

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();

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: