2017-02-10 2 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バージョンから何を取得し、私は何も意味しない:I場合*textModeを宣言時に初期化しないでください。初期化されていないポインタのままです。

これは正しいポインタですか?右?私はそれが分かっています。ポインタが必要です。私はこれらのうちの1つを理解するだろうが、ちょっと - 少なくとも私は仕事にリンクされたリストを持っている!わーい!

+0

あなたのプログラムがコンパイルされていない必要があります。

は、ここで私が考えていたものです。 – Shravan40

+0

それはうまくコンパイルされます。私は過去1時間それを振っていて、さまざまなことを試してきました。毎回コンパイルされています。 – alanlittle

+0

'int'を参考にして' char * 'を値として取る方法に注目してください。 – Kevin

答えて

1

第2の関数は、valint)を参考にして、となり、期待通りに渡される変数を変更することができます。

最初の関数はvalchar*)の値をvoid getEnv (char *val, const char *var)とします。したがって、valを変更すると、渡される変数には影響しません。簡単な解決策は、それを単に参考にしておくことです。void getEnv (char *&val, const char *var)

+0

ああ!そうですか。私はあなたがそれを行うことができるのか分からなかった - 私はちょうどそれがポインタなので、それはすでにアドレスを渡しているので、それは問題ではないと考えました。私は、それは 'nullptr'である' textMod'の* value *を渡していると思いますが、関数はそれを何もすることはできません。 OK、ありがとう。私はこのごろ1つを得るでしょう! – 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)、isSet_(false)'部分は、これらのメンバー変数を初期化するためのC++構文です。 –

関連する問題