我想在我正在编写的C ++程序中访问$HOME
环境变量。如果我用C编写代码,我只使用getenv()
函数,但我想知道是否有更好的方法来实现它。这是我到目前为止的代码:
std::string get_env_var( std::string const & key ) {
char * val;
val = getenv( key.c_str() );
std::string retval = "";
if (val != NULL) {
retval = val;
}
return retval;
}
我应该使用getenv()
来访问C ++中的环境变量吗?是否有任何我可能遇到的问题,我可以通过一些知识来避免这些问题?
答案 0 :(得分:59)
在C ++中使用getenv()
没有错。它由stdlib.h
定义,或者如果您更喜欢标准库实现,则可以包含cstdlib
并通过std::
命名空间(即std::getenv()
)访问该函数。这绝对没有错。事实上,如果您担心可移植性,则首选这两个版本中的任何一个。
如果您不关注可移植性并且您使用的是托管C ++,则可以使用.NET等效项 - System::Environment::GetEnvironmentVariable()
。如果你想要Windows的非.NET等价物,你可以简单地使用GetEnvironmentVariable()
Win32函数。
答案 1 :(得分:21)
我会稍微重构一下代码:
std::string getEnvVar( std::string const & key ) const
{
char * val = getenv( key.c_str() );
return val == NULL ? std::string("") : std::string(val);
}
答案 2 :(得分:17)
为什么在Windows中使用GetEnvironmentVariable,from MSDN getenv:
getenv仅对数据进行操作 运行时可访问的结构 图书馆而不是环境 为该过程创建的“段” 操作系统。因此, 使用envp参数的程序 main或wmain可能检索无效 信息。
此功能可以检索a 系统环境变量或用户 环境变量。
答案 3 :(得分:10)
在c ++中,你必须使用std :: getenv和#include <cstdlib>
答案 4 :(得分:1)
@Vlad的答案版本,带有一些错误检查,可以区分空值和缺失值:
inline std::string get_env(const char* key) {
if (key == nullptr) {
throw std::invalid_argument("Null pointer passed as environment variable name");
}
if (*key == '\0') {
throw std::invalid_argument("Value requested for the empty-name environment variable");
}
const char* ev_val = getenv(key);
if (ev_val == nullptr) {
throw std::runtime_error("Environment variable not defined");
}
return std::string(ev_val);
}
注意:
std::optional<std::string>
替换上面对异常的使用,或者将来用examples替换例外(如果最终被标准化)。key
到合理范围内的复制(例如100个字符?200个字符?),我还要检查这些字符是否可打印,以及std::expected
这些字符。 答案 5 :(得分:1)
是的,我知道这是一个旧线程!
尽管如此,根据定义,常见的错误并不新鲜。 :-)
我认为不只使用 std::getenv() 的唯一原因是添加已知默认值或在框架中采用通用模式/API .我也会在这种情况下避免异常(虽然不是一般情况下),因为非值返回通常足以成为环境变量的有效响应。增加处理异常的复杂性是违反直觉的。
这基本上就是我使用的:
const char* GetEnv( const char* tag, const char* def=nullptr ) noexcept {
const char* ret = std::getenv(tag);
return ret ? ret : def;
}
int main() {
int ret=0;
if( GetEnv("DEBUG_LOG") ) {
// Setup debug-logging
} else {
...
}
return (-1==ret?errno:0);
}
这个答案与其他答案之间的差异可能看起来很小,但我发现当您养成编码习惯时,这些小细节非常有益。
就像 getenv() 返回一个非常量 指针一样,这很容易导致坏习惯!