INI文件格式及其讀寫

ini文件(Initialization file),這種類型的文件中通常存放的是一個程序的初始化信息。ini文件由若干個節(Section)組成,每個Section由若干鍵(Key)組成,每個Key可以賦相應的值。讀寫ini文件實際上就是讀寫某個的Section中相應的Key的值,而這隻要藉助幾個函數即可完成。

1. 把信息寫入系統的win.ini文件

  1. BOOL WriteProfileString(  
  2. LPCTSTR lpAppName,     // 節的名字,是一個以0結束的字符串  
  3. LPCTSTR lpKeyName,      // 鍵的名字,是一個以0結束的字符串。若爲NULL,則刪除整個節  
  4. LPCTSTR lpString             // 鍵的值,是一個以0結束的字符串。若爲NULL,則刪除對應的鍵  
  5. )  

2、從系統的win.ini文件中讀取信息

  1. DWORD GetProfileString(  
  2. LPCTSTR lpAppName,            // 節名  
  3. LPCTSTR lpKeyName,             // 鍵名,讀取該鍵的值  
  4. LPCTSTR lpDefault,                // 若指定的鍵不存在,該值作爲讀取的默認值  
  5. LPTSTR lpReturnedString,     // 一個指向緩衝區的指針,接收讀取的字符串  
  6. DWORD nSize                          // 指定lpReturnedString指向的緩衝區的大小  
  7. )  
  1. UINT GetProfileInt(  
  2. LPCTSTR lpAppName,            // 同上  
  3. LPCTSTR lpKeyName,             // 同上  
  4. INT nDefault                             // 若指定的鍵名不存在,該值作爲讀取的默認值  
  5. )  

3.寫入讀取自己的ini

簡單的INI例子:

[html] view plaincopy
  1. [Service]  
  2. Name=AutoRun  Helper  
  3. Description=200  
  4. ApplicationRootKey64=Software\Wow6432Node\Sepang\AutoRun Modem  
  5. [Registry]  
  6. ServiceRootKey=Software\AutoRun Modem Service  
  7. ApplicationRootKey=Software\Sepang\AutoRun Modem  
  8. ApplicationRootKey64=Software\Wow6432Node\Sepang\AutoRun Modem  


下面示例顯示它是如何生成的:

  1. void XXXXX::OnBnClickedWriteIniBtn()  
  2. {  
  3.     // ----------------------------------------  
  4.     // 模擬寫入一個config.ini  
  5.     // ----------------------------------------  
  6.   
  7.     // 得到exe執行路徑.  
  8.     TCHAR tcExePath[MAX_PATH] = {0};  
  9.     ::GetModuleFileName(NULL, tcExePath, MAX_PATH);  
  10.     // 設置ini路徑到exe同一目錄下  
  11. #ifndef CONFIG_FILE  
  12. #define CONFIG_FILE     (TEXT("Config1.ini"))  
  13. #endif  
  14.     //_tcsrchr() 反向搜索獲得最後一個'\\'的位置,並返回該位置的指針  
  15.     TCHAR *pFind = _tcsrchr(tcExePath, '\\');  
  16.     if (pFind == NULL)  
  17.     {  
  18.         return;  
  19.     }  
  20.     *pFind = '\0';  
  21.       
  22.     CString szIniPath = tcExePath;  
  23.     szIniPath += "\\";  
  24.     szIniPath += CONFIG_FILE;  
  25.   
  26.     //--------------------------------------------------------  
  27.     //BOOL WritePrivateProfileString(  
  28.     //                              LPCTSTR lpAppName,      //節的名字,是一個以0結束的字符串  
  29.     //                              LPCTSTR lpKeyName,      //鍵的名字,是一個以0結束的字符串。若爲NULL,則刪除整個節  
  30.     //                              LPCTSTR lpString,       //鍵的值,是一個以0結束的字符串。若爲NULL,則刪除對應的鍵  
  31.     //                              LPCTSTR lpFileName      //要寫入的文件的文件名。若該ini文件與程序在同一個目錄下,  
  32.     //                              )                          也可使用相對路徑,否則需要給出絕度路徑。  
  33.     //如果Ini不存在,它會自動在szIniPath上創建此INI文件.再執行寫入.                             
  34.     ::WritePrivateProfileString(TEXT("Service"), TEXT("Name"), TEXT("AutoRun  Helper"), szIniPath);  
  35.     ::WritePrivateProfileString(TEXT("Service"), TEXT("Description"), TEXT("200"), szIniPath);  
  36.   
  37.     ::WritePrivateProfileString(TEXT("Registry"), TEXT("ServiceRootKey"), TEXT("Software\\AutoRun Modem Service"), szIniPath);  
  38.     ::WritePrivateProfileString(TEXT("Registry"), TEXT("ApplicationRootKey"), TEXT("Software\\Sepang\\AutoRun Modem"), szIniPath);  
  39.     ::WritePrivateProfileString(TEXT("Registry"), TEXT("ApplicationRootKey64"), TEXT("Software\\Wow6432Node\\Sepang\\AutoRun Modem"), szIniPath);  
  40.   
  41.     //這個說明不同節之中可以存在完全相同的鍵.  
  42.     ::WritePrivateProfileString(TEXT("Service"), TEXT("ApplicationRootKey64"), TEXT("Software\\Wow6432Node\\Sepang\\AutoRun Modem"), szIniPath);  
  43.   
  44.       
  45.     //下面執行讀取 ----------------------------------  
  46.     if (!::PathFileExists(szIniPath))  
  47.     {  
  48.         return;  
  49.     }  
  50.   
  51.     TCHAR szKeyValue[MAX_PATH] = {0};  
  52.     int nValue = 0;  
  53.   
  54.     //--------------------------------------------------------  
  55.     //DWORD GetPrivateProfileString(  
  56.     //                              LPCTSTR lpAppName,            // 節名  
  57.     //                              LPCTSTR lpKeyName,            // 鍵名,讀取該鍵的值  
  58.     //                              LPCTSTR lpDefault,            // 若指定的鍵不存在,該值作爲讀取的默認值  
  59.     //                              LPTSTR lpReturnedString,      // 一個指向緩衝區的指針,接收讀取的字符串  
  60.     //                              DWORD nSize,                  // 指定lpReturnedString指向的緩衝區的大小  
  61.     //                              LPCTSTR lpFileName            // 讀取信息的文件名。若該ini文件與程序在同一個目錄下,  
  62.     //                                                                也可使用相對路徑,否則需要給出絕度路徑  
  63.     //UINT GetPrivateProfileInt(  
  64.     //                              LPCTSTR lpAppName,            // 節名  
  65.     //                              LPCTSTR lpKeyName,            // 鍵名,讀取該鍵的值  
  66.     //                              INT nDefault,                 // 若指定的鍵名不存在,該值作爲讀取的默認值  
  67.     //                              LPCTSTR lpFileName            // 同上  
  68.     //  
  69.     //--------------------------------------------------------  
  70.   
  71.     ::GetPrivateProfileString(TEXT("Service"), TEXT("Name"), NULL, szKeyValue, MAX_PATH, szIniPath);  
  72.     nValue = ::GetPrivateProfileInt(TEXT("Service"), TEXT("Description"), 0, szIniPath);  
  73.   
  74.   
  75. }  

4.


四、如何判斷一個ini文件中有多少個節

要判斷一個ini文件中有多少個節,最簡單的辦法就是將所有的節名都找出來,然後統計節名的個數。而要將所有的節名找出來,使用GetPrivateProfileSectionNames函數就可以了,其原型如下:

DWORDGetPrivateProfileSectionNames(

LPTSTR lpszReturnBuffer,     // 指向一個緩衝區,用來保存返回的所有節名。

DWORD nSize,                         // 參數lpszReturnBuffer的大小。

LPCTSTR lpFileName               // 文件名,若該ini文件與程序在同一個目錄下,

// 也可使用相對路徑,否則需要給出絕度路徑。

)

下面的是用來統計一個ini文件中共有多少個節的函數,當然,如果需要同時找到每個節中的各個鍵及其值,根據找到節名就可以很容易的得到了。

/* 統計共有多少個節

節名的分離方法:若chSectionNames數組的第一字符是'\0'字符,則表明有0個節。

否則,從chSectionNames數組的第一個字符開始,順序往後找,直到找到一個'\0'字符,

若該字符的後繼字符不是'\0'字符,則表明前面的字符組成一個節名。

若連續找到兩個'\0'字符,則統計結束。 */

  1. TCHAR chSectionNames[2048] = {0};    
  2.     TCHAR *pSectionName;   // 保存找到的某個節名字符串的首地址。  
  3.     int j=0;               // j用來保存下一個節名字符串的首地址相對於當前i的位置偏移量。  
  4.     int count = 0;         // 統計節的個數。  
  5.   
  6.     ::GetPrivateProfileSectionNames(chSectionNames, 2048, szIniPath);  
  7.     for (i=0; i<2048; i++, j++)  
  8.     {  
  9.         if (chSectionNames[0] == '\0')  
  10.         {  
  11.             break;       // 如果第一個字符就是0,則說明ini中一個節也沒有。  
  12.         }  
  13.   
  14.         if (chSectionNames[i] == '\0')  
  15.         {  
  16.             // 找到一個’\0’,則說明從這個字符往前,減掉j個偏移量,就是一個節名的首地址。  
  17.             pSectionName = &chSectionNames[i-j];   
  18.             // 找到一個節名後,j的值要還原,以統計下一個節名地址的偏移量。  
  19.             // 賦成-1是因爲節名字符串的最後一個字符’\0’是終止符,不能作爲節名的一部分。  
  20.             j = -1;  
  21.   
  22.             // 在獲取節名的時候可以獲取該節中鍵的值,前提是我們知道該節中有哪些鍵。  
  23.             AfxMessageBox(pSectionName);   // 把找到的顯示出來。  
  24.   
  25.             if (chSectionNames[i+1] == 0)   //is 0 or ‘\0’?  
  26.             {  
  27.                 break;  // 當兩個相鄰的字符都是0時,則所有的節名都已找到,循環終止。  
  28.             }  
  29.         }  
  30.     }  


 

在VC程序中利用系統提供的GetPrivateProfileString及WritePrivateProfileString函數直接讀寫系統配置ini文件(指定目錄下的Ini文件)。

假設在當前目錄下有一個文件名爲Tets.ini的文件,用於保存用戶名和密碼,文件格式如下:

[Section1]

Item1= huzhifeng

Item2= 1234565

①寫INI文件

voidCINI_File_TestDlg::OnButtonWrite()

{

// TODO: Add your control notification handler code here

CStringstrSection = "Section1";

CStringstrSectionKey = "Item1";

charstrBuff[256];

CStringstrValue = _T("");

CStringstrFilePath;

strFilePath=GetCurrentDirectory(256,strBuff); // 獲取當前路徑。

strFilePath.Format("%s\\Test.ini",strBuff);

GetDlgItemText(IDC_EDIT_NAME,strValue);           // 獲取文本框內容:即姓名。

// 寫入ini文件中相應字段。

WritePrivateProfileString(strSection,strSectionKey,strValue,strFilePath);

strSectionKey= "Item2";

GetDlgItemText(IDC_EDIT_PASSWORD,strValue);      // 獲取文本框內容:即密碼。

WritePrivateProfileString(strSection,strSectionKey,strValue,strFilePath);

}

②讀INI文件內容

void CINI_File_TestDlg::OnButtonRead()

{

// TODO: Add your control notification handler code here

CString strSection ="Section1";

CString strSectionKey = "Item1";

char strBuff[256];

CString strValue = _T("");

CString strFilePath;

strFilePath=GetCurrentDirectory(256, strBuff);    //獲取當前路徑

strFilePath.Format("%s\\Test.ini", strBuff);

//讀取ini文件中相應字段的內容

GetPrivateProfileString( strSection, strSectionKey,

NULL, strBuff,

80, strFilePath);

strValue = strBuff;

SetDlgItemText(IDC_EDIT_NAME, strValue);

strSectionKey = "Item2";

GetPrivateProfileString( strSection, strSectionKey,

NULL, strBuff,

80, strFilePath);

strValue=strBuff;

SetDlgItemText(IDC_EDIT_PASSWORD, strValue);

UpdateData(FALSE);

}

 

原文出處:(半未勻)曾文獻老師

http://hi.baidu.com/__%B6%C0%B9%C2%B2%D0%D4%C6__/blog/item/79957c127edbd9c9c3fd78d0.html

BOOLIsFileExist(const char *szFileName) //判斷文件是否存在

{

CFileStatus stat;

if(CFile::GetStatus(szFileName,stat))

return TRUE;

else

return FALSE;

}

 

// 讀字符串

intReadINIString(CString INIFileName,CString INISection,CString Key,CString&Value) {

if(INIFileName=="" ||INISection=="" || Key=="") // 參數不對

{

Value.Format("%s",_T(""));

return -1;

}

if(!IsFileExist((LPTSTR)(LPCTSTR)INIFileName))   //ini文件不存在

{

Value.Format("%s",_T(""));

return -2;

}

::GetPrivateProfileString(INISection,Key,"",Value.GetBuffer(MAX_PATH),

MAX_PATH,INIFileName);

return 0;

}

 

//讀整形變量

intReadINIUInt(CString INIFileName,CString INISection,CString Key,UINT &Value)

{

if(INIFileName=="" ||INISection=="" || Key=="")//參數不對

{

Value=0;

return -1;

}

if(!IsFileExist((LPTSTR)(LPCTSTR)INIFileName))//ini文件不存在

{

Value=0;

return -2;

}

Value=::GetPrivateProfileInt(INISection,Key,0,INIFileName);

return 0;

}

 

//獲得應用程序的所在路徑

intGetAppPath(CString &AppPath)

{

try

{

CString MoudleFile;

//得到文件絕對路徑

GetModuleFileName(NULL,MoudleFile.GetBufferSetLength(MAX_PATH+1),MAX_PATH);

int pos=MoudleFile.ReverseFind(_T('\\'));

AppPath=MoudleFile.Left(pos+1);

}catch(...){

return -1;

}

return 0;

}

 

//按鈕事件調用相關函數

voidCReadWriteINIfieDlg::OnButton1()

{

// TODO: Add your control notification handler code here

CString FilePath;

//CString strServerToIEClientPort;

UINT iServerToIEClientPort;

GetAppPath(FilePath);

m_IniFileName.Format("%scc.ini",FilePath);

//ReadINIString(m_IniFileName,"ServerHost","Port",strServerToIEClientPort);

ReadINIUInt(m_IniFileName,"ServerHost","Port",iServerToIEClientPort);

ReadINIString(m_IniFileName,"ServerHost","DataFileName",strServerToIEClientPort);

}

 

//判斷文件是否存在

BOOLIsFileExist(const char *szFileName)

{

CFileStatus stat;

if(CFile::GetStatus(szFileName,stat))

return TRUE;

else

return FALSE;

}

 

intCSetDbData::GetIniData( CString INIFileName, CString INISection,

CString Key, CString &Value)

{

if(INIFileName=="" ||INISection=="" || Key=="")//參數不對

{

Value.Format("%s",_T(""));

return -1;

}

if(!IsFileExist((LPTSTR)(LPCTSTR)INIFileName))//ini文件不存在

{

Value.Format("%s",_T(""));

return -2;

}

::GetPrivateProfileString(INISection,Key,"",

Value.GetBuffer(MAX_PATH),MAX_PATH,INIFileName);

return 0;

}

 

intCSetDbData::SetIniData(CString INIFileName,CString INISection,

CString Key,CString Value)

{

if(INIFileName=="" ||INISection=="" || Key=="")//參數不對

{

Value.Format("%s",_T(""));

return -1;

}

if(!IsFileExist((LPTSTR)(LPCTSTR)INIFileName))//ini文件不存在

{

Value.Format("%s",_T(""));

return -2;

}

::WritePrivateProfileString(INISection,Key,Value,INIFileName);

return 0;

}

 

//刪除鍵

intCSetDbData::DelIniData(CString INIFileName,CString INISection)

{

if(INIFileName=="" ||INISection=="")//參數不對

{

return -1;

}

if(!IsFileExist((LPTSTR)(LPCTSTR)INIFileName))//ini文件不存在

{

return -2;

}

::WritePrivateProfileString(INISection,NULL,NULL,INIFileName);

return 0;

}

 

 

window平臺下讀寫ini文件的一個小小的實例

http://hi.baidu.com/zerowwj/blog/item/5b088ea790fc429ad043586f.html

/* ini文件的讀寫 */

#include<iostream>

#include<windows.h>

#include<atlstr.h>

usingnamespace std;

voidmain()

{

CString strName;

CString strTemp;

int nAge;

strName = "zhangsan";

nAge = 12;

 

/*

* 此函數功能是向文件stud.ini文件裏寫入一段配置項記錄:

* 其中配置段項名稱爲 "StudentInfo";配置項一個名稱爲Name;

* 其值爲CString類型變量strName所指的內容

*/

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

/*

* 此函數功能是向文件stud.ini文件裏寫入一段配置項記錄:

* 其中配置段項名稱爲 "StudentInfo";配置項一個名稱爲Age;

* 其值爲int類型變量nAge所指的內容,只是之前需要轉換成CString類型

* 最後要指定寫文件的路徑和名稱

*/

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

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

/*

* 以下爲讀出,讀出CString類型和int類型的方法不一樣。函數的具體的功能可以查看MSDN

*/

CString strStudName;

int nStuAge;

::GetPrivateProfileString("StudentInfo","Name","defualt",

strStudName.GetBuffer(MAX_PATH),

MAX_PATH,"d:\\stud.ini");

nStuAge =::GetPrivateProfileInt("StudentInfo","Age",10,"d:\\stud.ini");

cout<<"strStudName = "<<strStudName <<endl;

cout<<"nStuAge = "<< nStuAge<<endl;

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章