C++ getenv() 包装函数未设置值
C++ getenv() wrapper function not setting the value
关于 getenv()
的 cplusplus.com 文档指出...
The pointer returned points to an internal memory block, whose content or validity may be altered by further calls to getenv
...我的意思是,"If you want to keep the content, copy it." 因此,由于我需要检索多个变量,因此我编写了几个小包装函数:
#include <iostream>
#include <string.h>
using namespace std;
void getEnv (char *val, const char *var) {
val = nullptr;
char *enVar = getenv(var);
if (enVar != nullptr) {
val = new char[strlen(enVar) + 1];
strcpy(val, enVar);
}
}
void getEnv (int &val, const char *var) {
val = -1;
char *enVar = getenv(var);
if (enVar != nullptr) {
val = atoi(enVar);
}
}
int main() {
char *textMode = nullptr;
int cLen = 0;
getEnv(cLen, "CONTENT_LENGTH");
cout << cLen << endl << endl;
getEnv(textMode, "TEXT_MODE");
if (textMode == nullptr)
cout << "Not set.";
else
cout << "[" << textMode << "]<br>\n";
return 0;
}
int
版本按预期工作,但我从 char
版本中没有得到任何回报,我什么意思也没有:如果我不在声明时初始化 *textMode
它仍然存在一个未初始化的指针。
是指针,对吧?正确的?我知道它是。一定要指点我会在这些日子里弄清楚它们,但是嘿——至少我的链表可以工作了!耶!
您的第二个函数通过引用获取 val
(int
):void getEnv (int &val, const char *var)
因此可以按您的预期修改传递给它的变量。
您的第一个函数采用 val
(char*
)的值:void getEnv (char *val, const char *var)
因此修改 val
对传递给它的变量没有影响。一个简单的解决办法就是简单地把它也当作参考:void getEnv (char *&val, const char *var)
跟进我的评论和 OP 对它们的回应。
这是我的想法:
#include <iostream>
#include <string.h>
using namespace std;
// Use a class to encapsulate the data need to be captured
// in an environment variable.
class EnvironmentVariable
{
public:
EnvironmentVariable(char const* name) : name_(name), isSet_(false)
{
char *val = getenv(name);
if ( val != nullptr )
{
isSet_ = true;
this->value_ = val;
}
}
bool isSet() const
{
return isSet_;
}
void getValue(char const*& val) const
{
if ( isSet_ )
{
val = this->value_.c_str();
}
else
{
val = nullptr;
}
}
void getValue(int& val) const
{
if ( isSet_ )
{
val = stoi(this->value_);
}
else
{
val = 0; // Find a suitable default value
}
}
private:
std::string name_;
std::string value_;
bool isSet_;
};
int main() {
char const* textMode = nullptr;
int cLen = 0;
EnvironmentVariable env1("CONTENT_LENGTH");
env1.getValue(cLen);
cout << cLen << endl << endl;
EnvironmentVariable env2("TEXT_MODE");
env2.getValue(textMode);
if (textMode == nullptr)
cout << "Not set.\n";
else
cout << "[" << textMode << "]<br>\n";
return 0;
}
关于 getenv()
的 cplusplus.com 文档指出...
The pointer returned points to an internal memory block, whose content or validity may be altered by further calls to
getenv
...我的意思是,"If you want to keep the content, copy it." 因此,由于我需要检索多个变量,因此我编写了几个小包装函数:
#include <iostream>
#include <string.h>
using namespace std;
void getEnv (char *val, const char *var) {
val = nullptr;
char *enVar = getenv(var);
if (enVar != nullptr) {
val = new char[strlen(enVar) + 1];
strcpy(val, enVar);
}
}
void getEnv (int &val, const char *var) {
val = -1;
char *enVar = getenv(var);
if (enVar != nullptr) {
val = atoi(enVar);
}
}
int main() {
char *textMode = nullptr;
int cLen = 0;
getEnv(cLen, "CONTENT_LENGTH");
cout << cLen << endl << endl;
getEnv(textMode, "TEXT_MODE");
if (textMode == nullptr)
cout << "Not set.";
else
cout << "[" << textMode << "]<br>\n";
return 0;
}
int
版本按预期工作,但我从 char
版本中没有得到任何回报,我什么意思也没有:如果我不在声明时初始化 *textMode
它仍然存在一个未初始化的指针。
是指针,对吧?正确的?我知道它是。一定要指点我会在这些日子里弄清楚它们,但是嘿——至少我的链表可以工作了!耶!
您的第二个函数通过引用获取 val
(int
):void getEnv (int &val, const char *var)
因此可以按您的预期修改传递给它的变量。
您的第一个函数采用 val
(char*
)的值:void getEnv (char *val, const char *var)
因此修改 val
对传递给它的变量没有影响。一个简单的解决办法就是简单地把它也当作参考:void getEnv (char *&val, const char *var)
跟进我的评论和 OP 对它们的回应。
这是我的想法:
#include <iostream>
#include <string.h>
using namespace std;
// Use a class to encapsulate the data need to be captured
// in an environment variable.
class EnvironmentVariable
{
public:
EnvironmentVariable(char const* name) : name_(name), isSet_(false)
{
char *val = getenv(name);
if ( val != nullptr )
{
isSet_ = true;
this->value_ = val;
}
}
bool isSet() const
{
return isSet_;
}
void getValue(char const*& val) const
{
if ( isSet_ )
{
val = this->value_.c_str();
}
else
{
val = nullptr;
}
}
void getValue(int& val) const
{
if ( isSet_ )
{
val = stoi(this->value_);
}
else
{
val = 0; // Find a suitable default value
}
}
private:
std::string name_;
std::string value_;
bool isSet_;
};
int main() {
char const* textMode = nullptr;
int cLen = 0;
EnvironmentVariable env1("CONTENT_LENGTH");
env1.getValue(cLen);
cout << cLen << endl << endl;
EnvironmentVariable env2("TEXT_MODE");
env2.getValue(textMode);
if (textMode == nullptr)
cout << "Not set.\n";
else
cout << "[" << textMode << "]<br>\n";
return 0;
}