1. 程式人生 > >c/c++ 獲取當前程式(EXE)所在的路徑

c/c++ 獲取當前程式(EXE)所在的路徑

一、

1.只獲得路徑字串不包含檔名

TCHAR szFilePath[MAX_PATH + 1]={0};
GetModuleFileName(NULL, szFilePath, MAX_PATH);
(_tcsrchr(szFilePath, _T('\\')))[1] = 0; // 刪除檔名,只獲得路徑字串
CString str_url = szFilePath;  // 例如str_url==e:\program\Debug\
---------------------------------------------------------
2.獲得雙斜槓路徑不包含檔名

TCHAR _szPath[MAX_PATH + 1]={0};


GetModuleFileName(NULL, _szPath, MAX_PATH);
(_tcsrchr(_szPath, _T('\\')))[1] = 0;//刪除檔名,只獲得路徑 字串
CString strPath;
for (int n=0;_szPath[n];n++)
{
if (_szPath[n]!=_T('\\'))
{
strPath +=_szPath[n] ;
}
else
{
strPath += _T("\\\\");
}
}

MessageBox(strPath);//輸出==e:\\program\\Debug\\


二、
1:獲取應用程式自身完整路徑檔名
方法1:
#include "stdlib.h"


void main()
{
cout << _pgmptr << endl;
}

方法2:
char szFullPath[MAX_PATH];
ZeroMemory(szFullPath,MAX_PAT);
::GetModuleFileName(NULL,szFullPath,MAX_PATH);
::MessageBox(NULL,szFullPath,"path",MB_ICONINFORMATION);

方法3:
TCHAR szPath[MAX_PATH] = {0};
if(!GetModuleFileName(NULL, szPath, MAX_PATH))
{ return ; }


AfxMessageBox(szPath);

2:如何獲取應用程式所在目錄?
這裡值得注意的是很多人都用
GetCurrentDirectory(MAX_PATH, szCurrentPath);
來獲取。這個方法並不好,經常出錯,比如現在我有一個程式在d:\test目錄下,現在執行這個程式後用GetCurrentDirectory得到的是d:\test

。接著在程式裡用CFileDialog來開啟一個C:\test\test.txt檔案後再呼叫GetCurrentDirectory,那麼得到的szCurrentPath就是C:\test而不是d:\test。

推薦用如下方法來得到當前程式所在目錄比較安全:
void _splitpath( const char *path, char *drive, char *dir, char *fname, char *ext );
函式來分解開始提到的_pgmptr,然後再用
void _makepath( char *path, const char *drive, const char *dir, const char *fname, const char *ext );
函式來對分解後的路徑進行組合。這兩個函式結合起來功能強大,使用靈活,基本上所有的有關目錄和路徑方面的操作都可以搞定。

 MSDN的用法:

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. int main( void )  
  4. {  
  5.    char path_buffer[_MAX_PATH];  
  6.    char drive[_MAX_DRIVE];  
  7.    char dir[_MAX_DIR];  
  8.    char fname[_MAX_FNAME];  
  9.    char ext[_MAX_EXT];  
  10.    errno_t err;  
  11.    err = _makepath_s( path_buffer, _MAX_PATH, "c""\\sample\\crt\\",  
  12.                       "crt_makepath_s""c" );  
  13.    if (err != 0)  
  14.    {  
  15.       printf("Error creating path. Error code %d.\n", err);  
  16.       exit(1);  
  17.    }  
  18.    printf( "Path created with _makepath_s: %s\n\n", path_buffer );  
  19.    err = _splitpath_s( path_buffer, drive, _MAX_DRIVE, dir, _MAX_DIR, fname,  
  20.                        _MAX_FNAME, ext, _MAX_EXT );  
  21.    if (err != 0)  
  22.    {  
  23.       printf("Error splitting the path. Error code %d.\n", err);  
  24.       exit(1);  
  25.    }  
  26.    printf( "Path extracted with _splitpath_s:\n" );  
  27.    printf( "  Drive: %s\n", drive );  
  28.    printf( "  Dir: %s\n", dir );  
  29.    printf( "  Filename: %s\n", fname );  
  30.    printf( "  Ext: %s\n", ext );  
  31. }  

我自己寫了個合成當前EXE所在目錄某個檔案的完整路徑函式:

  1. void make_full_path(char* s, int nLen, constchar *file_name, constchar*file_ext)  
  2. {  
  3.     char szPath[MAX_PATH]={0};  
  4.     GetModuleFileNameA(NULL, szPath, MAX_PATH);  
  5.     char cDir[100] = "";  
  6.     char cDrive[10] = "";  
  7.     char cf[20] = "";  
  8.     char cExt[10] = "";  
  9.     _splitpath_s(szPath, cDrive, cDir, cf, cExt);  
  10.     _makepath_s(s, nLen, cDrive, cDir, file_name, file_ext);  
  11. }  
  1. string GetExePath(void)  
  2. {  
  3.     char szFilePath[MAX_PATH + 1]={0};  
  4.     GetModuleFileNameA(NULL, szFilePath, MAX_PATH);  
  5.     (strrchr(szFilePath, '\\'))[0] = 0; // 刪除檔名,只獲得路徑字串
  6.     string path = szFilePath;  
  7.     return path;  
  8. }  

引數說明:

s用來接收完整路徑;

nLen緩衝區長度;

file_name為檔名稱,不帶字尾;

file_ext為檔案字尾。

  1. FILE *f;  
  2. TCHAR szFilePath[MAX_PATH + 1]={0};  
  3. sprintf_s(szFilePath, "%s", g_file_in.c_str());  
  4. //GetModuleFileName(NULL, szFilePath, MAX_PATH);
  5. (strrchr(szFilePath, '.'))[1] = 0;   
  6. sprintf_s(szFilePath, "%soutput.txt", szFilePath);  
  7. fopen_s(&f, szFilePath, "a+");  
  8. fwrite(strLog.c_str(), 1, strlen(strLog.c_str()), f);  
  9. fclose(f);