1. 程式人生 > >利用GetPrivateProfileString讀取配置檔案(.ini)

利用GetPrivateProfileString讀取配置檔案(.ini)

利用GetPrivateProfileString讀取配置檔案(.ini)

我們寫的程式當中,總有一些配置資訊需要儲存下來,以便完成程式的功能,最簡單的辦法就是將這些資訊寫入INI檔案中,程式初始化時再讀入

配置檔案中經常用到ini檔案,在VC中其函式分別為:
寫入.ini檔案:bool WritePrivateProfileString(LPCTSTRlpAppName,LPCTSTR lpKeyName,LPCTSTR lpString,LPCTSTRlpFileName);

讀取.ini檔案:DWORD GetPrivateProfileString(LPCTSTRlpAppName,LPCTSTR lpKeyName,LPCTSTR lpDefaut,LPSTRlpReturnedString,DWORD nSize,LPCTSTR lpFileName);

讀取整形值:UINT GetPrivateProfileInt(LPCTSTR lpAppName,LPCTSTRlpKeyName,INT nDefault,LPCTSTR lpFileName);

其中個引數的意思:
LPCTSTR lpAppName ------- INI檔案中的一個欄位名
LPCTSTR lpKeyName -------- lpAppName 下的一個鍵名,也就是裡面具體的變數名
LPCTSTR lpString ---------是鍵值,也就是變數的值, 必須為LPCTSTR或CString型別
LPCTSTR lpFileName --------完整的INI檔案路徑名
LPCTSTR lpDefaut ----------如果沒有其前兩個引數值,則將此值賦給變數
LPSTR lpReturnedString --------接收INI檔案中的值的CString物件,即接收緩衝區
DWORD nSize ------接收緩衝區的大小
例子:
CString StrName,Strtemp;
int nAge;
StrName = “jacky”;
nAge = 13;
WritePrivateProfileString(“Student”,“Name”,StrName,“c:\setting.ini”);
結果:(INI檔案中顯示如下:)
[Student]
Name=jacky
讀取:
CString SName;
GetPrivateProfileString(“Student”,“Name”,“DefaultName”,SName.GetBuffer(MAX_LENGTH),MAX_LENGTH,“c:\setting.ini”);
結果:SName =“jacky”;這裡需要注意點就是用完GetBuffer函式後一定要釋放(用SName.ReleaseBuffer()函式),不然後面再用到SName的其他子函式就會失靈。
讀整數比較簡單,如下
int Result =GetPrivateProfileInt(“Student”,“nAge”,0,“c:\setting.ini”)返回值即為所讀取的結果!
在GetPrivateProfileString最後一個引數是配置檔案路徑的引數,此路徑只能是絕對路徑,不能是相對路徑,但現在我需要是我的exe檔案能和我的配置檔案在一起。因此我使用了GetCurrentDirectory函式。
原始碼如下:
CString server_ip;

CString des="";

::GetCurrentDirectory(MAX_PATHLENGTH,des.GetBuffer(MAX_PATHLENGTH));

des.ReleaseBuffer();

des+="\config.ini";
GetPrivateProfileString(“PhoneDemo”,“Server_IP”,"",server_ip.GetBufferSetLength(15),15,des);

server_ip.ReleaseBuffer();
注意:在這裡使用CString變數時,在使用完GetBuffer後,緊接著一定要使用ReleaseBuffer()函式,才可以進行其他的諸如字串+操作

例子:

CString StrName,Strtemp;

int nAge;

StrName = “jacky”;

nAge = 13;

WritePrivateProfileString(“Student”,“Name”,StrName,“c:\setting.ini”);

結果:(INI檔案中顯示如下:)

[Student]

Name=jacky

讀取:

CString SName;

GetPrivateProfileString(“Student”,“Name”,“DefaultName”,SName.GetBuffer(MAX_LENGTH),MAX_LENGTH,“c:\setting.ini”);

結果:SName =“jacky”;這裡需要注意點就是用完GetBuffer函式後一定要釋放(用SName.ReleaseBuffer()函式),不然後面再用到SName的其他子函式就會失靈。

讀整數比較簡單,如下

int Result = GetPrivateProfileInt(“Student”,“nAge”,0,“c:\setting.ini”)返回值即為所讀取的結果!

在GetPrivateProfileString最後一個引數是配置檔案路徑的引數,此路徑只能是絕對路徑,不能是相對路徑,但現在我需要是我的exe檔案能和我的配置檔案在一起。因此我使用了GetCurrentDirectory函式。

原始碼如下:

CString server_ip;

CString des="";

::GetCurrentDirectory(MAX_PATHLENGTH,des.GetBuffer(MAX_PATHLENGTH));

des.ReleaseBuffer();

des+="\config.ini";
GetPrivateProfileString(“PhoneDemo”,“Server_IP”,"",server_ip.GetBufferSetLength(15),15,des);

server_ip.ReleaseBuffer();

注意:在這裡使用CString變數時,在使用完GetBuffer後,緊接著一定要使用ReleaseBuffer()函式,才可以進行其他的諸如字串+操作

更多說明:

獲取路徑

GetCurrentDirectory只是返回當前程序的當前目錄,而並不是程序的映象檔案(.exe)所在的目錄
GetCurrentDirectory()適用於XP等系統,在WinCE上不能使用
GetModuleFileName()適用於WinCE2.0以後

使用方法:

//下面的一段程式碼主要是獲得當前程式的執行目錄(.exe)所在的目錄

{

CStringpath;

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

path.ReleaseBuffer();

int pos =path.ReverseFind('\\');

path =path.Left(pos);

}

GetModuleFileName函式

WINAPI DWORD GetModuleFileName(

HMODULE hModule,

LPWSTR lpFilename,

DWORD nSize

);

 GetBuffer和ReleaseBuffer是一套需要配合使用的函式,與GetBufferSetLength相比,優點是如果分配的空間大於實際儲存的字串(0結尾),

ReleaseBuffer會把多餘申請的空間釋放, 歸還給系統; 但使用時需要注意以下問題:如果要儲存的字串為abc(0結尾),則GetBuffer引數應至少

為3; 如果要儲存的內容不是以0結尾, 比如是讀取檔案資料,則GetBuffer引數如果大於檔案長度時,ReleaseBuffer引數一定要為檔案長度(如果

GetBuffer引數為檔案長度的話不存在問題,ReleaseBuffer引數可以為預設-1)!

GetBufferSetLength相對比較容易理解, 它申請一個指定長度的空間,即使裡面最終儲存的字串長度小於申請的空間長度, 也不會將多餘空間釋放.

__________________________________________________________________________________________________________________DWORDGetCurrentDirectory(

DWORD nBufferLength,

LPTSTR lpBuffer

);The GetCurrentDirectory function retrieves the current directoryfor the currentprocess.GetCurrentDirectory返回當前程序的當前目錄,並不一定返回你的應用程式的目錄。如果你在應用程式中呼叫了開啟檔案對話方塊,你選擇了一個檔案,那麼,這個檔案所在的目錄就成了當前程序的當前目錄了。Parameters

nBufferLength: 接收儲存路徑的字串快取長度, 快取必須有一個儲存結束的空字元的位置.

lpBuffer:指向接收字串的快取,收到的非空字串指定了當前目錄的絕對路徑.

DWORD GetModuleFileName(

HMODULE hModule,

LPTSTR lpFilename,

DWORD nSize

);

GetModuleFileName 函式指定當前程序模組的路徑.它僅僅操作當前程序下的模組.如果想獲取其他程序下的模組資訊, 則需使用GetModuleFileNameEx 函式.Parameters

hModule:模組的控制代碼,或者設定為NULL表示當前模組。

lpFilename:儲存路徑的緩衝區。

nSize:緩衝區的大小。

例子: TCHAR strExePath[_MAX_PATH];

GetModuleFileName(NULL,strExePath,_MAX_PATH);PathRemoveFileSpec(strExePath);如果當前執行程式的位置為c:\test.exe,GetModuleFileName獲取的strExePath即為c:\test.ext,通過去掉名稱函式最終獲得的strExePath為c:。(注意PathRemoveFileSpec系統API函式呼叫時必須包含#include
"Shlwapi.h"作為標頭檔案) TCHARstrExePath[_MAX_PATH];

GetCurrentDirectory(_MAX_PATH, strExePath);獲取當前的系統目錄,可能是c:也可能是其他值。


shlwapi.dll

shlwapi - shlwapi.dll - DLL檔案資訊

DLL 檔案: shlwapi 或者 shlwapi.dll

DLL 名稱: Microsoft Shell Light-weight Utility Library

描述:   shlwapi.dll是UNC和URL地址動態連結庫檔案,用於註冊鍵值和色彩設定。

屬於: Microsoft Windows Shell

系統 DLL檔案: 是

常見錯誤: File Not Found, Missing File, Exception Errors

安全等級 (0-5): 0   間諜軟體: 否   廣告軟體: 否

VC中使用GetModuleFileName獲取應用程式路徑

.\與API函式GetModuleFileName獲取應用程式目錄有何不一樣?
採用.\也能獲得應用程式目錄,採用GetModuleFileName也能獲得,二者有何不同?

一樣!

一個是相對路徑,一個是絕對路徑
.\是得到應用程式的當前目錄,但當前目錄不一定等於應用程式執行檔案的所在目錄,一個應用程式被啟動時,當前目錄是可以被任意設定的。
GetModuleFileName()得到模組的完整路徑名,例如,你載入c:\windows\system32\a.dll,得到模組控制代碼h,則你可以用GetModuleFileName()得到h模組的完整路徑名。

.\一般用在包含標頭檔案的語句中。

另一個是程式編譯後起作用的,例如,開啟自定義的配置檔案等。

如何去取得這個Hanlde?

如果你直接用LoadLibrary()或AfxLoadLibrary()載入dll,該函式返回值就是handle;

如果你隱式載入dll, 用GetModuleHandle(“dll檔名”)也可以得到handle;

MFC程式得到本身路徑

在開發工程中,往往需要知道當前程式本身所在目錄。

一種方法是在程式安裝的時候利用安裝程式把檔案路徑寫入登錄檔。在較大的程式中,這種方法比較常用

另一種,就是在程式得到路徑。這樣,程式隨便移動到哪裡,都可以得到正確的路徑。這也是本文介紹的方法。

方法一:

[code]

//得到幫助檔案的路徑

CString strFullName = AfxGetApp()->m_pszHelpFilePath;

//得到的是:X:\XXXX\XXX.hlp

//解析路徑,得到當前執行程式所在目錄

char drive[_MAX_DRIVE];

char dir[_MAX_DIR];

_splitpath(strAppName,drive, dir, NULL,NULL);
CString strPath;

strPath.Format("%s%s", drive, dir);

//strPath即為得到的當前執行程式所在目錄

[/code]

另外,AfxGetApp()->m_pszAppName得到應用程式名稱
AfxGetApp()->m_pszExeName得到程式檔名,不包括副檔名

方法二:

得到全路徑

TCHAR exeFullPath[MAX_PATH]; // MAX_PATH

GetModuleFileName(NULL,exeFullPath,MAX_PATH);//得到程式模組名稱,全路徑

也就是當前執行程式的全路徑

利用方法一的解析路徑的方法,即可得到程式所在路徑。

GetModuleFileName函式原型

DWORD GetModuleFileName(

HMODULEhModule, // handle to module。將要得到的模組的控制代碼。如果是當前模組,NULL

LPTSTRlpFilename, // pathbuffer 得到的檔名。

DWORDnSize) // size of buffer 一般MAX_PATH就可以了