WinApi操作ini文件

   在我们写的程序当中,总有一些配置信息需要保存下来,以便完成程序的功能,最简单的办法就是将这些信息写入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(); 

*/



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值