用Visual C++操作INI文件 .

来源:互联网 发布:原声吉他音箱 知乎 编辑:程序博客网 时间:2024/06/06 07:52
 在我们写的程序当中,总有一些配置信息需要保存下来,以便完成程序的功能,最简单的办法就是将这些信息写入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();*/


 

原创粉丝点击