【问题标题】:C++ getenv() wrapper function not setting the valueC ++ getenv()包装函数未设置值
【发布时间】:2017-02-10 21:17:41
【问题描述】:

getenv() 上的 cplusplus.com 文档指出...

返回的指针指向一个内部内存块,其内容或有效性可以通过进一步调用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,它仍然是一个未初始化的指针。

是指针,对吧?正确的?我知道它是。应该是指点这些天我会弄清楚它们,但是嘿-至少我的链接列表可以工作了!耶!

【问题讨论】:

  • 你的程序不能在编译。
  • 它编译得很好。在过去的一个小时里我一直在摆弄它,尝试了各种各样的东西,并且每次都能编译。
  • 请注意您如何将int 用作参考,但将char* 视为值。
  • 是的,因为我不需要为int 分配内存。 intint,所以我可以通过引用传递它,但 char 必须是一个指针,以便我可以为它分配内存。
  • 分配内存与此无关。在这两种情况下,您都在修改 val,但这仅在作为参考时才会产生外部影响。看我的回答。

标签: c++ pointers getenv


【解决方案1】:

您的第二个函数通过引用获取valint):void getEnv (int &amp;val, const char *var),因此可以按照您的预期修改传递给它的变量。

您的第一个函数按值获取valchar*):void getEnv (char *val, const char *var) 因此修改val 对传递给它的变量没有影响。一个简单的解决方案是简单地将其作为参考:void getEnv (char *&amp;val, const char *var)

【讨论】:

  • 啊!我懂了。我不知道你能做到这一点——我只是想,因为它是一个指针,它已经在传递一个地址,所以这不会是一个问题。不过,我想我明白了——它传递了textMod,即nullptr,而函数对此无能为力。好,谢谢。这些天我会得到它!
【解决方案2】:

跟进我的 cmets 和 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;
}

【讨论】:

  • 我喜欢。几个问题:1)这是什么: name_(name), isSet_(false)我猜它分配了默认值?为什么不在构造函数中这样做呢? name_ 不在任何地方使用。 2)你不delete val(见我上面的最后一条评论)。没有必要吗?
  • @alanlittle, name_ 可用。您可以添加成员函数std::string getName() const; 以提供对环境变量名称的访问。
  • @alanlittle,: name_(name), isSet_(false) 部分是用于初始化这些成员变量的 C++ 语法。
猜你喜欢
  • 2014-05-01
  • 2013-04-02
  • 2011-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-17
  • 1970-01-01
相关资源
最近更新 更多