2016-12-06 123 views
0

我正在用C++創建一個遊戲引擎,並且我已經開始添加對加載文件的支持。我創建了一個看起來像這樣的負載文件的方法:C++ - 你如何獲得C++可執行文件的當前目錄?

#include <string> 
#include <fstream> 

std::string read_file(const char* filepath) { 

     FILE* file = fopen(filepath, "rt"); 
     if(file != NULL) { 
      fseek(file, 0, SEEK_END); 
     } else { 
      std::string error_message = std::string("[ERROR]: Failed to load file "); 
      error_message.append(filepath); 
      return error_message; 
     } 
     unsigned long length = ftell(file); 
     char* data = new char[length + 1]; 
     memset(data, 0, length + 1); 
     fseek(file, 0, SEEK_SET); 
     fread(data, 1, length, file); 
     fclose(file); 

     std::string result(data); 
     delete[] data; 

     return result; 

    } 

爲了測試這個功能,我決定嘗試加載「的test.txt」的文件,但是這不會工作,除非我包括完整路徑,例如

"/Users/(Username)/.../(Executable Directory)/text.txt" 

,而不是僅僅

"test.txt" 

因此,要解決這個問題,我需要一種方式來獲得的可執行文件所在的目錄的完整路徑,然後追加文件名稱到結束的路徑,並加載我的加載文件方法。

任何人都知道如何獲得路徑?

回答

0

像這樣的事情會找到你在Windows/Ubuntu的/ Mac OS X中的可執行文件:

#include <vector> 

#include <boost/filesystem.hpp> 

#if defined(_WIN32) 
    #include <windows.h> 
#elif defined(__linux__) 
    #include <sstream> 
    #include <unistd.h> 
#elif defined(__APPLE__) 
    #include <mach-o/dyld.h> 
#endif 

boost::filesystem::path find_executable() 
{ 
    unsigned int bufferSize = 512; 
    std::vector<char> buffer(bufferSize + 1); 

#if defined(_WIN32) 
    ::GetModuleFileName(NULL, &buffer[0], bufferSize); 

#elif defined(__linux__) 
    // Get the process ID. 
    int pid = getpid(); 

    // Construct a path to the symbolic link pointing to the process executable. 
    // This is at /proc/<pid>/exe on Linux systems (we hope). 
    std::ostringstream oss; 
    oss << "/proc/" << pid << "/exe"; 
    std::string link = oss.str(); 

    // Read the contents of the link. 
    int count = readlink(link.c_str(), &buffer[0], bufferSize); 
    if(count == -1) throw std::runtime_error("Could not read symbolic link"); 
    buffer[count] = '\0'; 

#elif defined(__APPLE__) 
    if(_NSGetExecutablePath(&buffer[0], &bufferSize)) 
    { 
    buffer.resize(bufferSize); 
    _NSGetExecutablePath(&buffer[0], &bufferSize); 
    } 

#else 
    #error Cannot yet find the executable on this platform 
#endif 

    std::string s = &buffer[0]; 
    return s; 
} 

從這一點,你可以用parent_path()得到包含它的目錄。

此解決方案的一個缺點是,您需要使用Boost(特別是Boost.Filesystem),但如果這對您沒有問題,那麼它應該可以很好地工作(僅供參考,這是代碼我實際上每天都會使用這個功能,而且它的確運行良好,至少對於我需要的功能)。如果這是一個問題,它可以適用於消除對Boost.Filesystem的依賴,而不會有太多麻煩。

+0

不是名爲'find_executable()'的函數嗎? –

+0

@RavenH .:找到可執行文件的函數叫做'find_executable'。要獲取包含它的目錄,可以調用'find_executable'返回的路徑上的'parent_path()'。 –

相關問題