我想在hpp文件中存储文件夹的绝对路径;路径存储在公共类中。我试过用:
static constexpr const char* FOLDER_PATH = "$HOME/catkin_ws/src/abc/pqr/xyz"
但是,$HOME
似乎无效。我可以获得$HOME
的解决方法吗?如果我写/home/myname/
它似乎工作正常。我不想写/home/myname/
; 问题是我每次在不同系统上运行代码时都需要更改。我不想每次都编辑;文件夹结构保持不变。
答案 0 :(得分:1)
C ++中的跨平台主目录
要在运行时获取HOME目录(意味着它无法在编译时确定,因此无法将其存储为标头中的常量),您可以使用getenv
(或在Windows上,{{1因为路径应该是支持Unicode的,所以在Windows上使用广泛的API。)
<强> POSIX 强>
您可以假设使用_wgetenv
环境变量指定路径。
HOME
<强>窗强>
Miles Budnek建议的一个简单的解决方案是使用#include <cstdlib>
#include <string>
std::string get_home()
{
char *dir = getenv("HOME");
if (dir != nullptr) {
return std::string(dir);
} else {
// home not defined, root user, maybe return "/root"
// this code path should generally **not** occur.
return std::string("/");
}
}
函数。
GetUserProfileDirectory
如果您想依赖环境变量,这不是那么容易,但最好的解决方案是检查#include <windows.h>
#include <string>
std::wstring get_home()
{
DWORD size = 0;
HANDLE token = GetCurrentProcessToken();
// get the size needed for the buffer.
GetUserProfileDirectoryW(token, NULL, &size);
if (size == 0) {
throw std::runtime_error("Unable to get required size.\n");
}
// this won't work pre-C++11, since strings weren't guaranteed
// to be continuous
std::wstring home(size, 0);
if (!GetUserProfileDirectoryW(token, &home[0], &size)) {
throw std::runtime_error(("Unable to get home directory.\n");
}
return home;
}
,然后检查USERPROFILE
,然后检查HOME
和{{1}如果没有设置,那么HOMEDRIVE
作为后备。这可以解决:
HOMEPATH
为什么不使用WordExp?
SystemDrive
不保证是Windows编译器的一部分,并且在Windows上无法正常运行。此外,不保证在Windows上设置#include <cstdlib>
#include <stdexcept>
#include <string>
std::wstring get_home()
{
// check USERPROFILE
wchar_t *home = _wgetenv(L"USERPROFILE");
if (home != nullptr) {
return std::wstring(home);
}
// check HOME
home = _wgetenv(L"HOME");
if (home != nullptr) {
return std::wstring(home);
}
// combine HOMEDRIVE and HOMEPATH
wchar_t *drive = _wgetenv(L"HOMEDRIVE");
wchar_t *path = _wgetenv(L"HOMEPATH");
if (drive != nullptr && path != nullptr) {
// "c:", "\users\{user}"
return std::wstring(drive) + std::wstring(path);
}
// try SystemDrive
home = _wgetenv(L"SystemDrive");
if (home != nullptr) {
return std::wstring(home);
} else {
return std::wstring(L"c:");
}
}
。您应该使用wordexp
。此外,HOME
执行shell扩展,这意味着将扩展许多其他符号(包括(_w)getenv
,字符集和其他环境变量),这可能是不可取的。这很简单,跨平台,范围有限。