ini文件(Initialization file),這種類型的文件中通常存放的是一個程序的初始化信息。ini文件由若干個節(Section)組成,每個Section由若干鍵(Key)組成,每個Key可以賦相應的值。讀寫ini文件實際上就是讀寫某個的Section中相應的Key的值,而這隻要藉助幾個函數即可完成。
1. 把信息寫入系統的win.ini文件
- BOOL WriteProfileString(
- LPCTSTR lpAppName, // 節的名字,是一個以0結束的字符串
- LPCTSTR lpKeyName, // 鍵的名字,是一個以0結束的字符串。若爲NULL,則刪除整個節
- LPCTSTR lpString // 鍵的值,是一個以0結束的字符串。若爲NULL,則刪除對應的鍵
- )
2、從系統的win.ini文件中讀取信息
- DWORD GetProfileString(
- LPCTSTR lpAppName, // 節名
- LPCTSTR lpKeyName, // 鍵名,讀取該鍵的值
- LPCTSTR lpDefault, // 若指定的鍵不存在,該值作爲讀取的默認值
- LPTSTR lpReturnedString, // 一個指向緩衝區的指針,接收讀取的字符串
- DWORD nSize // 指定lpReturnedString指向的緩衝區的大小
- )
- UINT GetProfileInt(
- LPCTSTR lpAppName, // 同上
- LPCTSTR lpKeyName, // 同上
- INT nDefault // 若指定的鍵名不存在,該值作爲讀取的默認值
- )
3.寫入讀取自己的ini
簡單的INI例子:
- [Service]
- Name=AutoRun Helper
- Description=200
- ApplicationRootKey64=Software\Wow6432Node\Sepang\AutoRun Modem
- [Registry]
- ServiceRootKey=Software\AutoRun Modem Service
- ApplicationRootKey=Software\Sepang\AutoRun Modem
- ApplicationRootKey64=Software\Wow6432Node\Sepang\AutoRun Modem
下面示例顯示它是如何生成的:
- void XXXXX::OnBnClickedWriteIniBtn()
- {
- // ----------------------------------------
- // 模擬寫入一個config.ini
- // ----------------------------------------
- // 得到exe執行路徑.
- TCHAR tcExePath[MAX_PATH] = {0};
- ::GetModuleFileName(NULL, tcExePath, MAX_PATH);
- // 設置ini路徑到exe同一目錄下
- #ifndef CONFIG_FILE
- #define CONFIG_FILE (TEXT("Config1.ini"))
- #endif
- //_tcsrchr() 反向搜索獲得最後一個'\\'的位置,並返回該位置的指針
- TCHAR *pFind = _tcsrchr(tcExePath, '\\');
- if (pFind == NULL)
- {
- return;
- }
- *pFind = '\0';
- CString szIniPath = tcExePath;
- szIniPath += "\\";
- szIniPath += CONFIG_FILE;
- //--------------------------------------------------------
- //BOOL WritePrivateProfileString(
- // LPCTSTR lpAppName, //節的名字,是一個以0結束的字符串
- // LPCTSTR lpKeyName, //鍵的名字,是一個以0結束的字符串。若爲NULL,則刪除整個節
- // LPCTSTR lpString, //鍵的值,是一個以0結束的字符串。若爲NULL,則刪除對應的鍵
- // LPCTSTR lpFileName //要寫入的文件的文件名。若該ini文件與程序在同一個目錄下,
- // ) 也可使用相對路徑,否則需要給出絕度路徑。
- //如果Ini不存在,它會自動在szIniPath上創建此INI文件.再執行寫入.
- ::WritePrivateProfileString(TEXT("Service"), TEXT("Name"), TEXT("AutoRun Helper"), szIniPath);
- ::WritePrivateProfileString(TEXT("Service"), TEXT("Description"), TEXT("200"), szIniPath);
- ::WritePrivateProfileString(TEXT("Registry"), TEXT("ServiceRootKey"), TEXT("Software\\AutoRun Modem Service"), szIniPath);
- ::WritePrivateProfileString(TEXT("Registry"), TEXT("ApplicationRootKey"), TEXT("Software\\Sepang\\AutoRun Modem"), szIniPath);
- ::WritePrivateProfileString(TEXT("Registry"), TEXT("ApplicationRootKey64"), TEXT("Software\\Wow6432Node\\Sepang\\AutoRun Modem"), szIniPath);
- //這個說明不同節之中可以存在完全相同的鍵.
- ::WritePrivateProfileString(TEXT("Service"), TEXT("ApplicationRootKey64"), TEXT("Software\\Wow6432Node\\Sepang\\AutoRun Modem"), szIniPath);
- //下面執行讀取 ----------------------------------
- if (!::PathFileExists(szIniPath))
- {
- return;
- }
- TCHAR szKeyValue[MAX_PATH] = {0};
- int nValue = 0;
- //--------------------------------------------------------
- //DWORD GetPrivateProfileString(
- // LPCTSTR lpAppName, // 節名
- // LPCTSTR lpKeyName, // 鍵名,讀取該鍵的值
- // LPCTSTR lpDefault, // 若指定的鍵不存在,該值作爲讀取的默認值
- // LPTSTR lpReturnedString, // 一個指向緩衝區的指針,接收讀取的字符串
- // DWORD nSize, // 指定lpReturnedString指向的緩衝區的大小
- // LPCTSTR lpFileName // 讀取信息的文件名。若該ini文件與程序在同一個目錄下,
- // 也可使用相對路徑,否則需要給出絕度路徑
- //UINT GetPrivateProfileInt(
- // LPCTSTR lpAppName, // 節名
- // LPCTSTR lpKeyName, // 鍵名,讀取該鍵的值
- // INT nDefault, // 若指定的鍵名不存在,該值作爲讀取的默認值
- // LPCTSTR lpFileName // 同上
- //
- //--------------------------------------------------------
- ::GetPrivateProfileString(TEXT("Service"), TEXT("Name"), NULL, szKeyValue, MAX_PATH, szIniPath);
- nValue = ::GetPrivateProfileInt(TEXT("Service"), TEXT("Description"), 0, szIniPath);
- }
4.
四、如何判斷一個ini文件中有多少個節
要判斷一個ini文件中有多少個節,最簡單的辦法就是將所有的節名都找出來,然後統計節名的個數。而要將所有的節名找出來,使用GetPrivateProfileSectionNames函數就可以了,其原型如下:
DWORDGetPrivateProfileSectionNames(
LPTSTR lpszReturnBuffer, // 指向一個緩衝區,用來保存返回的所有節名。
DWORD nSize, // 參數lpszReturnBuffer的大小。
LPCTSTR lpFileName // 文件名,若該ini文件與程序在同一個目錄下,
// 也可使用相對路徑,否則需要給出絕度路徑。
)
下面的是用來統計一個ini文件中共有多少個節的函數,當然,如果需要同時找到每個節中的各個鍵及其值,根據找到節名就可以很容易的得到了。
/* 統計共有多少個節
節名的分離方法:若chSectionNames數組的第一字符是'\0'字符,則表明有0個節。
否則,從chSectionNames數組的第一個字符開始,順序往後找,直到找到一個'\0'字符,
若該字符的後繼字符不是'\0'字符,則表明前面的字符組成一個節名。
若連續找到兩個'\0'字符,則統計結束。 */
- TCHAR chSectionNames[2048] = {0};
- TCHAR *pSectionName; // 保存找到的某個節名字符串的首地址。
- int j=0; // j用來保存下一個節名字符串的首地址相對於當前i的位置偏移量。
- int count = 0; // 統計節的個數。
- ::GetPrivateProfileSectionNames(chSectionNames, 2048, szIniPath);
- for (i=0; i<2048; i++, j++)
- {
- if (chSectionNames[0] == '\0')
- {
- break; // 如果第一個字符就是0,則說明ini中一個節也沒有。
- }
- if (chSectionNames[i] == '\0')
- {
- // 找到一個’\0’,則說明從這個字符往前,減掉j個偏移量,就是一個節名的首地址。
- pSectionName = &chSectionNames[i-j];
- // 找到一個節名後,j的值要還原,以統計下一個節名地址的偏移量。
- // 賦成-1是因爲節名字符串的最後一個字符’\0’是終止符,不能作爲節名的一部分。
- j = -1;
- // 在獲取節名的時候可以獲取該節中鍵的值,前提是我們知道該節中有哪些鍵。
- AfxMessageBox(pSectionName); // 把找到的顯示出來。
- if (chSectionNames[i+1] == 0) //is 0 or ‘\0’?
- {
- break; // 當兩個相鄰的字符都是0時,則所有的節名都已找到,循環終止。
- }
- }
- }
在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;
}