我正在用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 :(得分:3)
这样的东西会在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的依赖而不会有太多麻烦。