【问题标题】:C++ - How do you get the current directory of the C++ executable? [duplicate]C++ - 如何获取 C++ 可执行文件的当前目录? [复制]
【发布时间】:2017-04-20 13:28:00
【问题描述】:

我正在用 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"

所以,为了解决这个问题,我需要一种方法来获取可执行文件所在目录的完整路径,然后将文件名附加到路径的末尾,然后在我的加载文件方法中加载它。

有人知道如何获取路径吗?

【问题讨论】:

    标签: c++ macos path executable


    【解决方案1】:

    这样的东西会在 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 的依赖,而不会有太多麻烦。

    【讨论】:

    • 函数不是叫find_executable()吗?
    • @RavenH.:查找可执行文件的函数称为find_executable。要获取包含它的目录,您可以在调用 find_executable 返回的路径上调用 parent_path()
    猜你喜欢
    • 1970-01-01
    • 2011-02-19
    • 2011-01-18
    • 2018-04-17
    • 2012-08-28
    • 1970-01-01
    • 2018-10-17
    • 2014-07-31
    • 2017-04-16
    相关资源
    最近更新 更多