.ini 文件是Initialization File的縮寫,即初始化文件,是windows的系統配置文件所采用的存儲格式,來配置應用軟件以實現不同用戶的要求。配置文件有很多種如ini配置文件,XML配置文件,系統注冊表等。在早期的windows桌面系統中主要是用ini文件作為系統的配置文件,從win95以后開始轉向使用注冊表,但是還有很多系統配置是使用INI文件的。其實INI文件就是簡單的txt文件,只不過這種txt文件要遵循一定的INI文件格式。
ini文件由節、鍵、值組成:
節
[section]
參數(鍵=值)
name=value
注解
注解使用分號表示(;)。在分號后面的文字,直到該行結尾都全部為注解。
ini文件中可以存在多個小節(Section),每個小節的開始用包括在一對方括號中的小節名稱指定,不同的小節不能重名,一個小節的內容從小節名稱的下一行開始,直到下一個小節開始為止。用戶程序可以按照自己的需求建立多個小節。因為ini文件可能是項目中共用的,所以使用[section]來區分不同用途的參數區。例如:[Section1 Name]表示傳感器靈敏度參數區;[Section2 Name]表示測量通道參數區等等。INI所包含的最基本的“元素”就是parameter,每一個parameter都有一個name和一個value,name和value是由等號“=”隔開,name在等號的左邊。如:name = value
Windows提供了一系列函數(包含winbase.h或windows.h頭文件即可使用)來讀寫ini文件:
- 將信息寫入.INI文件中
BOOL WritePrivateProfileStringA( LPCSTR lpAppName, // section name LPCSTR lpKeyName, // key name. If this parameter is NULL, the entire section, including all entries within the section, is deleted. LPCSTR lpString, // string to add. If this parameter is NULL, the key pointed to by the lpKeyName parameter is deleted. LPCSTR lpFileName // initialization file );
BOOL WritePrivateProfileSectionW( LPCWSTR lpAppName, LPCWSTR lpString, LPCWSTR lpFileName );
當這些參數全部指定為字符串的時候,函數將在指定INI文件的指定小節中寫入“鍵名=鍵值”格式的行;當指定的INI文件、文件中的小節和小節中的鍵名都已經存在的時候,函數用新鍵值替換原來的鍵值;當指定的INI文件存在而小節不存在的時候,函數自動創建小節並將鍵寫入;如果連指定的INI文件也不存在的話,函數會自動創建文件。總之,程序不必考慮INI文件是否存在,小節是否存在或鍵值定義是否存在等情況,只要調用WritePrivateProfileString函數就可以保證配置信息被正確保存。
WritePrivateProfileString函數也可以用來刪除鍵或者小節,當lpAppName和lpKeyName參數指定了小節名稱和鍵名,而lpString參數指定為NULL的時候,函數將指定的鍵刪除。也可以將lpKeyName和lpString參數全部指定為NULL,而lpAppName參數指定小節名稱,那么將會刪除lpAppName參數指定的小節。
注意如果定義了UNICODE使用的函數實際上為WritePrivateProfileStringW。可以使用_T()宏或TEXT()宏:TEXT() 在定義 UNICODE 情況下使用 UNICODE 字符,否則使用 ANSI 字符。
#ifdef UNICODE #define WritePrivateProfileString WritePrivateProfileStringW #else #define WritePrivateProfileString WritePrivateProfileStringA #endif // !UNICODE
- 將信息從INI文件中讀入程序中的變量
DWORD GetPrivateProfileString( LPCTSTR lpAppName, // If this parameter is NULL, the GetPrivateProfileString function copies all section names in the file to the supplied buffer.
LPCTSTR lpKeyName, // If this parameter is NULL, all key names in the section specified by the lpAppNameparameter are copied to the buffer specified by the lpReturnedString parameter.
LPCTSTR lpDefault, // If the lpKeyName key cannot be found in the initialization file, GetPrivateProfileString copies the default string to the lpReturnedString buffer.
LPTSTR lpReturnedString, // destination buffer
DWORD nSize, // size of destination buffer
LPCTSTR lpFileName // The name of the initialization file
);
函數的返回值是返回到緩沖區中的字符串長度。lpReturnedString參數指向一個緩沖區,函數在這里返回獲取的鍵值字符串,緩沖區的長度用nSize參數指定,當緩沖區的長度太小以至於無法容納返回的字符串時,字符串會被截止到nSize-1的長度后返回,余下的一個字節用來存放一個a null character(0字符:'\0')做結尾。lpDefault參數指向一個默認字符串,當指定的鍵無法找到的時候,函數將這個字符串拷貝到返回緩沖區中。
GetPrivateProfileString還有兩種特殊用法:
(1)當lpAppName參數指定為NULL的時候,函數在緩沖區中返回的是全部小節名稱的列表,每個小節名以0結尾,全部的名稱列表再以一個附加的0結束,返回到緩沖區中的數據格式如下所示:
小節名稱1,0,小節名稱2,0,…,小節名稱n,0,0
(2)當lpAppName參數指定了小節名稱,而lpKeyName參數指定為NULL的時候,函數在緩沖區中返回該小節的全部鍵名列表,每個鍵名以0結尾,全部列表后面再以一個附加的0結束,如下所示:
鍵名1,0,鍵名2,0,…,鍵名n,0,0
因此可以用這兩種方式來枚舉INI文件中的節名以及各個節中的鍵名。
下面代碼在VS項目目錄中創建了一個test.ini的文件:
#include <windows.h> int main() { WritePrivateProfileString(TEXT("Section1"), TEXT("FirstKey"), TEXT("Value1"), TEXT(".\\test.ini")); WritePrivateProfileString(TEXT("Section1"), TEXT("SecondKey"), TEXT("Value2"), TEXT(".\\test.ini")); // Test TCHAR inBuf[80]; int ret = GetPrivateProfileString(TEXT("Section1"), TEXT("FirstKey"), TEXT("Error: failed"), inBuf, 80, TEXT(".\\test.ini")); _tprintf(TEXT("Key: %s\n"), inBuf); return 0; }
test.ini文件內容如下:
[Section1] FirstKey=Value1 SecondKey=Value2
GetPrivateProfileString函數獲取FirstKey的值Value后將其打印在屏幕上,輸出為:
Key: Value1
如果將接收數組長度改為3,可以看到結果被截斷,GetPrivateProfileString函數返回值為3-1=2:
當lpKeyName參數指定為NULL的時候,函數在緩沖區中返回該小節的全部鍵名列表:
當lpAppName參數指定為NULL的時候,函數在緩沖區中返回的是全部小節名稱的列表:
如果key的值為整數,那么還可以使用GetPrivateProfileInt函數來讀取。該函數返回鍵值對應的整數
UINT GetPrivateProfileInt( LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault, //The default value to return if the key name cannot be found in the initialization file. LPCTSTR lpFileName );
比如下面的ini文件,可以用GetPrivateProfileInt函數獲取Section2中AnotherKey的值,將返回整型數字2。如果獲取其它section中的鍵值將返回默認值。
[Section1]
FirstKey=Value1
SecondKey=Value2
[Section2]
AnotherKey=2
代碼如下:

#include <windows.h> int main() { WritePrivateProfileString(TEXT("Section1"), TEXT("FirstKey"), TEXT("Value1"), TEXT(".\\test.ini")); WritePrivateProfileString(TEXT("Section1"), TEXT("SecondKey"), TEXT("Value2"), TEXT(".\\test.ini")); WritePrivateProfileString(TEXT("Section2"), TEXT("AnotherKey"), TEXT("2"), TEXT(".\\test.ini")); // Test TCHAR inBuf[80]; int ret = GetPrivateProfileString(TEXT("Section1"), TEXT("FirstKey"), TEXT("Error: failed"), inBuf, 80, TEXT(".\\test.ini")); _tprintf(TEXT("Key: %s\n"), inBuf); // Get keys in section1 GetPrivateProfileString(TEXT("Section1"), NULL, TEXT("Error: failed"), inBuf, 80, TEXT(".\\test.ini")); // Retrieves an integer associated with a key in the specified section of an initialization file. UINT i = GetPrivateProfileInt(TEXT("Section2"), TEXT("AnotherKey"), 0, TEXT(".\\test.ini")); printf("integer value: %d", i); return 0; }
參考: