C++中路徑操作


C++中路徑操作

1.獲取當前應用程序所在路徑

1.1 方法:GetModuleFileName

GetModuleFileName聲明:

DWORD WINAPI GetModuleFileName(
_In_opt_  HMODULE hModule,
_Out_     LPTSTR lpFilename,
_In_      DWORD nSize
);

其中:
hModule —— 一個模塊的句柄。可以是一個DLL模塊,或者是一個應用程序的實例句柄。如果該參數為NULL,該函數返回該應用程序全路徑;
lpFilename —— 指定一個字串緩沖區,要在其中容納文件的用NULL字符中止的路徑名;
nSize —— 裝載到緩沖區lpFileName的最大字符數量。經常用_MAX_PATH;
_MAX_PATH是C語言運行時庫中通過#define指令定義的一個宏常量,它定義了編譯器所支持的最長全路徑名的長度。在VC++6.0中,值為260;Windows SDK中也有一個相應的變量MAX_PATH,值也是260。

1.2 獲取全路徑后獲取當前程序的運行目錄(.exe)所在的目錄

TCHAR exeFullPath[MAX_PATH + 1];
GetModuleFileName(NULL, atcExeFullPath, MAX_PATH);
CString path = atcExeFullPath;
path = path.Left(path.ReverseFind('\\'));

2.路徑分解

2.1 方法:_tsplitpath_s

頭文件:stdlib.h

_tsplitpath_s聲明(不同編碼方式下有不同的定義):

errno_t _splitpath_s(
   const char * path,
   char * drive,
   size_t driveNumberOfElements,
   char * dir,
   size_t dirNumberOfElements,
   char * fname,
   size_t nameNumberOfElements,
   char * ext,
   size_t extNumberOfElements
);
errno_t _wsplitpath_s(
   const wchar_t * path,
   wchar_t * drive,
   size_t driveNumberOfElements,
   wchar_t *dir,
   size_t dirNumberOfElements,
   wchar_t * fname,
   size_t nameNumberOfElements,
   wchar_t * ext,
   size_t extNumberOfElements
); 
template <size_t drivesize, size_t dirsize, size_t fnamesize, size_t extsize>  
errno_t _splitpath_s(  
   const char *path,  
   char (&drive)[drivesize],  
   char (&dir)[dirsize],  
   char (&fname)[fnamesize],  
   char (&ext)[extsize]  
); // C++ only  
template <size_t drivesize, size_t dirsize, size_t fnamesize, size_t extsize>  
errno_t _wsplitpath_s(  
   const wchar_t *path,  
   wchar_t (&drive)[drivesize],  
   wchar_t (&dir)[dirsize],  
   wchar_t (&fname)[fnamesize],  
   wchar_t (&ext)[extsize]  
); // C++ only 

各個參數的意義:

[in] path:全路徑
[out] drive:驅動器號,后跟一個冒號(:),如果你不需要驅動器號,可以傳遞NULL  
[in] driveNumberOfElements:Drive的緩沖區大小(單字節或寬字節),如果drive為NULL,該參數必須為0
[out] dir:目錄路徑,包括尾部的斜杠,可以使用“\”,“/”或者都使用,如果不需要目錄路徑,可以傳遞NULL
[in] dirNumberOfElements:Dir的緩沖區大小(單字節或者款字節),如果dir為NULL,該參數必須為0
[out] fname:不帶擴展名的文件名,如果不需要文件名,可以傳遞NULL
[in] nameNumberOfElements:Fname的緩沖區大小(單字節或者寬字節),如果fname為NULL,該參數必須為0
[out] ext:文件的擴展名,包括“.”,如果不需要擴展名,可以傳遞NULL
[in] extNumberOfElements:Ext的緩沖區大小(單字節或者寬字節),如果ext為NULL,該參數必須為0

返回值:
    成功返回0,失敗返回錯誤代碼 EINVAL

EINVAL情形:
  (1) path為NULL;
  (2)drive、dir、fname、ext這四個緩沖區指針中存在NULL,但是緩沖區對應的NumberOfElements !=0;
  (3)drive、dir、fname、ext這四個緩沖區對應的NumberOfElements =0,但是緩沖區指針不為NULL。
補充:
  如果任何一個緩沖區太短而無法包含結果,那么該函數會清空所有緩沖區指向空。設置errno 為ERANGE,並返回ERANGE。

2.2各部分允許最大值

  該函數將全路徑分割成四個部分,分別是驅動器,路徑名,文件名(不帶擴展名),擴展名。C語言運行時庫定義的每個部分允許的最大值為分別為_MAX_DRIVE, _MAX_DIR, _MAX_FNAME, _MAX_EXT,而Window SDK中每個部分允許的最大值為分別為_MAX_DRIVE, _MAX_DIR, _MAX_FNAME, _MAX_EXT,這些宏定義在stdlib.h中,如果這四個部分的緩沖區大小超過了定義的允許的最大值,那么會引起 heap corruption.

CRT library與Windows SDK中定義的四個量對應相等,以下是四個宏的定義的最大值:
  _MAX_DRIVE  3
  _MAX_DIR   256
  _MAX_FNAME 256
  _Max_EXT   256

3.路徑合成

3.1 方法:_tmakepath_s

頭文件:stdlib.h

_tmakepath_s聲明:

errno_t _makepath_s(  
   char *path,  
   size_t sizeInBytes,  
   const char *drive,  
   const char *dir,  
   const char *fname,  
   const char *ext   
);  
errno_t _wmakepath_s(  
   wchar_t *path,  
   size_t sizeInWords,  
   const wchar_t *drive,  
   const wchar_t *dir,  
   const wchar_t *fname,  
   const wchar_t *ext   
);  
template <size_t size>  
errno_t _makepath_s(  
   char (&path)[size],  
   const char *drive,  
   const char *dir,  
   const char *fname,  
   const char *ext   
); // C++ only  
template <size_t size>  
errno_t _wmakepath_s(  
   wchar_t (&path)[size],  
   const wchar_t *drive,  
   const wchar_t *dir,  
   const wchar_t *fname,  
   const wchar_t *ext   
); // C++ only  

各個參數的意義:

[out] path:完整路徑緩沖區。
[in] sizeInWords:緩沖區大小(以單詞為單位)。
[in] sizeInBytes:緩沖區的大小(以字節為單位)。
[in] drive:包含一個與所需的驅動器對應的字母(A、B 等)和可選的尾隨冒號。 如果缺少冒號,則 _makepath_s 會自動在復合路徑中插入冒號。 如果 drive 為 NULL 或指向空字符串,則在復合 path 字符串中不會顯示驅動器號。
[in] dir:包含目錄路徑,但不包括驅動器指示符或實際文件名。 尾隨斜杠是可選的和正斜杠 (/) 或反斜杠 (\) 或兩者可能使用在單個dir參數。 如果尾部反斜杠 (/ 或\) 指定,則它將自動進行插入。 如果 dir 為 NULL 或指向空字符串,則在復合 path 字符串中不會插入目錄路徑。
[in] fname:包含無任何文件擴展名的基文件名。 如果 fname 為 NULL 或指向空字符串,則在復合 path 字符串中不會插入文件名。
[in] ext:包含實際的文件擴展名(帶有或不帶前導句點 (.))。 如果 _makepath_s 中未顯示句點,則 ext 會自動插入句點。 如果 ext 為 NULL 或指向空字符串,則在復合 path 字符串中不會插入擴展名。

 // 取得當前應用程序所在路徑,包括程序文件名與后綴名
TCHAR drive[_MAX_DRIVE], dir[MAX_PATH], fname[MAX_PATH], ext[_MAX_EXT];
TCHAR exeFullPath[MAX_PATH];
GetModuleFileName(NULL, exeFullPath, MAX_PATH);
//分解
_tsplitpath_s(exeFullPath, drive, dir, fname, ext);  
// 去掉應用程序文件名與后綴名
TCHAR exeFullDir[MAX_PATH];
//合並
_tmakepath_s(exeFullDir, drive, dir, _T(""), _T(""));


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM