2017-02-10 56 views
0

getenv()状态的cplusplus.com文档...C++的getenv()包装函数不设置值

指针返回指向内部存储器块,其内容或有效性可通过进一步的呼叫被改变到getenv

......我认为,“如果你想保留内容,请复制它。”所以,因为我需要检索几个变量,我写了一对夫妇的小包装函数:

#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它仍然是未初始化的指针。

这是指针,对不对?对?我知道它是。得指点。我会在这些日子里找出他们的一个,但是嘿 - 至少我让我的链表工作了!好极了!

+0

你的程序不能编译。 – Shravan40

+0

它编译得很好。我在过去的一个小时里一直在摆弄它,尝试各种各样的东西,并且每次都编译。 – alanlittle

+0

请注意,您如何将'int'作为参考,但是通过值来获取'char *'。 – Kevin

回答

1

你的第二个函数接受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)

+0

啊!我懂了。我不知道你可以这样做 - 我只是想到了,因为它是一个指针,它已经传递了一个地址,所以它不会是一个问题。不过,我想我会看到,它传递的是'textMod'的* value *,它是'nullptr',并且该函数对此无能为力。好,谢谢。我会在这些日子里得到它! – alanlittle

0

跟随我的意见和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; 
} 
+0

我喜欢它。几个问题:1)这是什么?:name_(name),isSet_(false)'我猜它分配了默认值?为什么不在构造函数中这么做呢?并且'name_'不在任何地方使用。 2)你不'删除val'(见我上面的最后一条评论)。没有必要吗? – alanlittle

+0

@alanlittle,可以使用'name_'。您可以添加一个成员函数'std :: string getName()const;'来提供对环境变量名称的访问。 –

+0

@alanlittle,':name_(name),setSet_(false)'部分是用于初始化这些成员变量的C++语法。 –