• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 16,  comments - 81,  trackbacks - 0

            用Visual C++操作INI文件

            在我們寫的程序當中,總有一些配置信息需要保存下來,以便完成程序的功能,最簡單的辦法就是將這些信息寫入INI文件中,程序初始化時再讀入.具體應用如下:

            一.將信息寫入.INI文件中.

            1.所用的WINAPI函數(shù)原型為:

            BOOL WritePrivateProfileString(
            LPCTSTR lpAppName,
            LPCTSTR lpKeyName,
            LPCTSTR lpString,
            LPCTSTR lpFileName
            );

            其中各參數(shù)的意義:

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

              LPCTSTR lpKeyName 是lpAppName下的一個鍵名,通俗講就是變量名.

             LPCTSTR lpString 是鍵值,也就是變量的值,不過必須為LPCTSTR型或CString型的.

             LPCTSTR lpFileName 是完整的INI文件名.

            2.具體使用方法:設現(xiàn)有一名學生,需把他的姓名和年齡寫入 c:\stud\student.ini 文件中.

            CString strName,strTemp;
            int nAge;
            strName="張三";
            nAge=12;
            ::WritePrivateProfileString("StudentInfo","Name",strName,"c:\\stud\\student.ini");

            此時c:\stud\student.ini文件中的內(nèi)容如下:

            [StudentInfo]
            Name=張三

            3.要將學生的年齡保存下來,只需將整型的值變?yōu)樽址图纯?

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

            二.將信息從INI文件中讀入程序中的變量.

            1.所用的WINAPI函數(shù)原型為:

            DWORD GetPrivateProfileString(
            LPCTSTR lpAppName, 
            LPCTSTR lpKeyName, 
            LPCTSTR lpDefault, 
            LPTSTR lpReturnedString, 
            DWORD nSize, 
            LPCTSTR lpFileName 
            );

            其中各參數(shù)的意義:

            前二個參數(shù)與 WritePrivateProfileString中的意義一樣.

              lpDefault : 如果INI文件中沒有前兩個參數(shù)指定的字段名或鍵名,則將此值賦給變量.

             lpReturnedString : 接收INI文件中的值的CString對象,即目的緩存器.

             nSize : 目的緩存器的大小.

             lpFileName : 是完整的INI文件名.

            2.具體使用方法:現(xiàn)要將上一步中寫入的學生的信息讀入程序中.

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

             執(zhí)行后 strStudName 的值為:"張三",若前兩個參數(shù)有誤,其值為:"默認姓名".

            3.讀入整型值要用另一個WINAPI函數(shù):

            UINT GetPrivateProfileInt(
            LPCTSTR lpAppName, 
            LPCTSTR lpKeyName, 
            INT nDefault, 
            LPCTSTR lpFileName 
            );

            這里的參數(shù)意義與上相同.使用方法如下:

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

            三.循環(huán)寫入多個值,設現(xiàn)有一程序,要將最近使用的幾個文件名保存下來,具體程序如下:

            1.寫入:

            CString strTemp,strTempA;
            int i;
            int nCount=6;
            file://共有6個文件名需要保存
            for(i=0;i<nCount;i++) 
            {
              strTemp.Format("%d",i);
              strTempA=文件名;
              //文件名可以從數(shù)組,列表框等處取得.
              ::WritePrivateProfileString("UseFileName","FileName"+strTemp,strTempA,"c:\\usefile\\usefile.ini");
            }
            strTemp.Format("%d",nCount);
            ::WritePrivateProfileString("FileCount","Count",strTemp,"c:\\usefile\\usefile.ini");
            //將文件總數(shù)寫入,以便讀出.

            2.讀出:

            nCount=::GetPrivateProfileInt("FileCount","Count",0,"c:\\usefile\\usefile.ini");
            for(i=0;i<nCount;i++)
            {
              strTemp.Format("%d",i);
              strTemp="FileName"+strTemp;
              ::GetPrivateProfileString("CurrentIni",strTemp,"default.fil", strTempA.GetBuffer(MAX_PATH),MAX_PATH,"c:\\usefile\\usefile.ini");
              //使用strTempA中的內(nèi)容.
            }

            補充四點:
             1.INI文件的路徑必須完整,文件名前面的各級目錄必須存在,否則寫入不成功,該函數(shù)返回 FALSE 值.
             2.文件名的路徑中必須為 \\ ,因為在VC++中, \\ 才表示一個 \ .
             3.也可將INI文件放在程序所在目錄,此時 lpFileName 參數(shù)為: ".\\student.ini".

            //----------------------------------------------------------------------------------
            /*
            類名:CIni
            版本:v2.0
            加入高級操作的功能
            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是指段名及鍵名未存在時,是否創(chuàng)建。
            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);  //枚舉出一段內(nèi)的全部鍵名及值

            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)
            {
            /*
            本函數(shù)基礎:
            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);

            //以下循環(huán),截斷到兩個連續(xù)的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();//清空原數(shù)組

            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)
            {
            /*
            本函數(shù)基礎:
            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();//清空原數(shù)組
            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();
            */

            操作配置文件ini
            1.基礎知識
                INI文件(Initialization file ,又稱為初始化文件)是用來保存應用程序設置和選項的一種特殊的ASCII文件,以“.ini”作為文件擴展名,也被稱做配置文件或概要文件(Profile)。除了各個應用程序可以擁有自己私有的初始化文件外,Windows系統(tǒng)還提供有一個系統(tǒng)的初始化文件Win.ini,并由此對當前的Windows系統(tǒng)進行配置,同時也可以在其內(nèi)記錄系統(tǒng)內(nèi)其他應用程序在運行時的選項。

              通常為應用程序所私有的初始化文件比較小,這樣可以減少程序在初始化時所讀取的信息量,從而提高程序的啟動速度。而系統(tǒng)初始化文件Win.ini由于除了記錄有關系統(tǒng)的大量信息外,還存儲著許多其他應用軟件的初始化數(shù)據(jù),因此其通常比較龐大,訪問的數(shù)據(jù)量要遠比私有的配置文件大得多。如沒有必要,一般不建議對Win.ini文件進行操作,但如果待存取的信息涉及到Windows系統(tǒng)環(huán)境或是其他應用程序時, 就必須對Win.ini進行讀寫訪問,并在訪問的同時發(fā)送WM_WININICHANGE消息給所有的頂層窗口,通知其他進程系統(tǒng)初始化文件已被更改。

              配置文件里的信息之所以能為系統(tǒng)和眾多不同類型的應用程序讀取并識別,是由于其內(nèi)部對數(shù)據(jù)的存取采用了預先約定的“項-值對(Entry-value pairs)”存儲結構, 并對待存取的數(shù)據(jù)分門別類地進行存儲。下面是系統(tǒng)目錄下Win.ini文件的部分內(nèi)容:

            [windows] 
            load= 
            run= 
            NullPort=None 
            [Desktop] 
            WallpaperStyle=2 
            Pattern=(無) 

               在此,配置文件將信息分為若干“節(jié)”,節(jié)標題放在方括號中,如“[Desktop]”就是Desktop節(jié),在每一個節(jié)中包含了一些與之相關的“項”,并通過等號對其進行賦值。一般形式如下:

            [SECTION] 
            ENTRY=VALUE 

              在初始化文件中,VALUE值只能有兩種數(shù)據(jù)類型:數(shù)值和字符串。Windows分別為這兩種數(shù)據(jù)類型提供了兩套API函數(shù)對初始化文件進行數(shù)據(jù)讀取,在寫入初始化文件時則只支持對字符串的寫入,數(shù)值等類型必須先進行數(shù)據(jù)類型的轉(zhuǎn)換,然后才能寫入到初始化文件。私有初始化文件的訪問  對私有初始化文件的數(shù)據(jù)存取是由GetPrivateProfileInt()、GetPrivateProfileString()和WritePrivateProfileString()等三個API函數(shù)來完成的。其函數(shù)說明如下:

            UINT GetPrivateProfileInt(LPCTSTR lpAppName, // 節(jié)名地址
                                      LPCTSTR lpKeyName, // 項名地址
                                      INT nDefault,      // 在項名沒有找到時返回的缺省值
                                      LPCTSTR lpFileName // 初始化文件名地址
            );

            DWORD GetPrivateProfileString(LPCTSTR lpAppName, // 節(jié)名地址
                                          LPCTSTR lpKeyName, // 項名地址
                                          LPCTSTR lpDefault, // 缺省字符串
                                          LPTSTR lpReturnedString, // 存放字符串的緩沖區(qū)地址
                                          DWORD nSize, // 緩沖區(qū)大小
                                          LPCTSTR lpFileName // 初始化文件名地址
            );

            BOOL WritePrivateProfileString(LPCTSTR lpAppName, // 節(jié)名地址
                                           LPCTSTR lpKeyName, // 項名地址
                                           LPCTSTR lpString,  // 要寫入的字符串地址
                                           LPCTSTR lpFileName // 初始化文件名地址
            );

                其中,GetPrivateProfileInt()返回的是初始化文件lpFileName中l(wèi)pAppName節(jié)內(nèi)lpKeyName項的整數(shù)值,如果沒有找到該項則返回缺省值nDefault。如果此項目存在,但值不為整數(shù),則返回0。如果某項目的值中含有非數(shù)字字符則只返回第一個非數(shù)字前的字符,例如對于“Value = 21century”則只返回數(shù)值21。初始化文件名lpFileName可以是全路徑也可以只是文件名,如果不指定具體路徑,Windows系統(tǒng)將在系統(tǒng)目錄對文件進行尋找。GetPrivateProfileString()和WritePrivateProfileString()的用法基本與之類似,只是處理對象的數(shù)據(jù)類型不同。

            2 知識應用
              私有初始化文件主要用來保存同應用程序當前狀態(tài)相關的一些信息,當程序退出后,這些信息由于已寫入到初始化文件而得以保留,當程序再次運行時,可以通過對此初始化文件各項數(shù)據(jù)的讀取而得知此應用程序在上次運行期間的相關信息。下面這段代碼即通過對私有初始化文件的訪問而對程序的運行次數(shù)和上一次的運行日期進行記錄:

            CString sPath,sMsg,sTime,sDate;
            char buffer[255];

            // 獲取當前應用程序全路徑
            GetModuleFileName(NULL, buffer, MAX_PATH);
            sPath = CString(buffer);
            sPath = sPath.Left(sPath.ReverseFind('\\'));

            // 得到初始化文件的全路徑
            sPath += "\\Sample04.ini";

            // 得到程序累計運行次數(shù)
            UINT Time = GetPrivateProfileInt("PROGRAM", "RUNTIME", 0, sPath);

            // 得到上次運行日期
            GetPrivateProfileString("DATE", "LAST", "2002-11-1", buffer, 1000, sPath);

            // 顯示從初始化文件獲取到的文件信息
            sMsg.Format("本軟件共運行過%d次,上次運行日期為%s", Time, CString(buffer));
            AfxMessageBox(sMsg);

            // 累加運行次數(shù),并保存到初始化文件
            Time++;
            sTime.Format("%d", Time);
            WritePrivateProfileString("PROGRAM", "RUNTIME", sTime, sPath);

            // 獲取當前日期,并保存到初始化文件
            CTime tm = CTime::GetCurrentTime();
            sDate.Format("%d-%d-%d", tm.GetYear(), tm.GetMonth(), tm.GetDay());
            WritePrivateProfileString("DATE", "LAST", sDate, sPath);

            在程序執(zhí)行后,初始化文件Sample04.ini的內(nèi)容為:
            [DATE]
            LAST =2002-11-12
            [PROGRAM]
            RUNTIME =1

               系統(tǒng)目錄下的Win.ini是一種特殊的初始化文件,主要為系統(tǒng)提供初始化服務,在系統(tǒng)啟動時將被系統(tǒng)所訪問,并根據(jù)其所保存的參數(shù)值對系統(tǒng)進行配置。Windows專門提供了三個API函數(shù)GetProfileInt()、GetProfileString()和WriteProfileString()對Win.ini進行讀寫訪問,其函數(shù)用法同訪問私有初始化文件的那幾個函數(shù)非常類似,只是不必再去指定初始化文件名。下面是這三個函數(shù)的原型聲明:

            UINT GetProfileInt(LPCTSTR lpAppName, // 節(jié)名地址
                               LPCTSTR lpKeyName, // 項名地址
                               INT nDefault // 在項名沒有找到時返回的缺省值
            );

            DWORD GetProfileString(LPCTSTR lpAppName, // 節(jié)名地址
                                   LPCTSTR lpKeyName, // 項名地址
                                   LPCTSTR lpDefault, // 缺省字符串地址
                                   LPTSTR lpReturnedString, // 存放字符串的緩存的地址
                                   DWORD nSize // 緩存的大小
            );

            BOOL WriteProfileString(LPCTSTR lpAppName, // 節(jié)名地址
                                    LPCTSTR lpKeyName, // 項名地址
                                    LPCTSTR lpString   // 要寫入字符串的地址
            );

             

              只要對前面對私有初始化文件進行訪問的代碼稍加改動即可將程序的配置信息添加到Win.ini中,改動后的代碼如下:

            CString sPath,sMsg,sTime,sDate;

            // 得到程序累計運行次數(shù)
            UINT Time = GetProfileInt("PROGRAM", "RUNTIME", 0);

            // 得到上次運行日期
            GetProfileString("DATE", "LAST", "2002-11-1", buffer, 1000);

            // 顯示從初始化文件獲取到的文件信息
            sMsg.Format("本軟件共運行過%d次,上次運行日期為%s", Time, CString(buffer));
            AfxMessageBox(sMsg);

            // 累加運行次數(shù),并保存到初始化文件
            Time++;
            sTime.Format("%d", Time);
            WriteProfileString("PROGRAM", "RUNTIME", sTime);

            // 獲取當前日期,并保存到初始化文件
            CTime tm = CTime::GetCurrentTime();
            sDate.Format("%d-%d-%d", tm.GetYear(), tm.GetMonth(), tm.GetDay());
            WriteProfileString("DATE", "LAST", sDate);

               由于Win.ini文件是系統(tǒng)初始化文件,在程序沒有運行前文件內(nèi)不含“DATE”和“PROGRAM”等自定義的節(jié)以及其下各項,因此在程序第一次執(zhí)行后,將由WriteProfileString()函數(shù)向Win.ini文件末尾創(chuàng)建相關節(jié)、項,并完成數(shù)據(jù)的寫入。

            posted on 2010-09-27 18:14 叫我老王吧 閱讀(5127) 評論(0)  編輯 收藏 引用 所屬分類: 轉(zhuǎn)貼
            <2010年9月>
            2930311234
            567891011
            12131415161718
            19202122232425
            262728293012
            3456789

            常用鏈接

            留言簿(4)

            隨筆分類

            隨筆檔案

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            国产麻豆精品久久一二三| 免费精品久久天干天干| 久久精品国产亚洲AV无码娇色 | 亚洲人成网亚洲欧洲无码久久 | 久久WWW免费人成—看片| 久久性精品| 久久国产精品无码HDAV| 91久久精品视频| 亚洲国产精品无码久久一区二区| 99久久精品国产麻豆| 日产精品久久久久久久| 国产亚洲欧美成人久久片| 亚洲午夜福利精品久久 | 久久人人超碰精品CAOPOREN| 亚洲av成人无码久久精品| 99久久婷婷国产一区二区| 亚洲AV无一区二区三区久久| 久久亚洲色一区二区三区| 色综合久久最新中文字幕| 亚洲精品无码久久一线| 久久精品亚洲福利| 久久亚洲国产中v天仙www| 久久w5ww成w人免费| 久久久噜噜噜久久中文字幕色伊伊| 国产精品熟女福利久久AV| 色诱久久久久综合网ywww| 人妻无码αv中文字幕久久琪琪布| 国产2021久久精品| 色综合久久久久| 成人a毛片久久免费播放| 青青青青久久精品国产| 国产精品青草久久久久婷婷| 丰满少妇高潮惨叫久久久| 久久久久久人妻无码| 久久精品aⅴ无码中文字字幕重口| 久久亚洲春色中文字幕久久久| 亚洲精品第一综合99久久| 国产成人综合久久精品红| 欧美黑人激情性久久| 色综合久久夜色精品国产| 国内精品久久久久影院薰衣草 |