88

$HOME私が書いている C++ プログラムで環境変数にアクセスしたいと思います。もし私が 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++ で環境変数にアクセスするために使用する必要がありますか? 少しの知識で回避できる、遭遇する可能性が高い問題はありますか?

4

6 に答える 6

78

getenv()C++で使用しても問題はありません。によって定義されstdlib.hます。または、標準ライブラリの実装を好む場合は、名前空間 (つまり、 )cstdlibを介して関数を含めてアクセスできます。これはまったく問題ありません。実際、移植性が気になる場合は、これら 2 つのバージョンのどちらかをお勧めします。std::std::getenv()

移植性を気にせず、マネージ C++ を使用している場合は、同等の .NET を使用できます - System::Environment::GetEnvironmentVariable(). Windows 用の .NET 以外の同等物が必要な場合は、単にGetEnvironmentVariable()Win32 関数を使用できます。

于 2009-03-10T18:45:44.600 に答える
35

コードを少しリファクタリングします。

std::string getEnvVar( std::string const & key ) const
{
    char * val = getenv( key.c_str() );
    return val == NULL ? std::string("") : std::string(val);
}
于 2011-03-23T05:30:25.707 に答える
20

MSDN getenv から、Windows で GetEnvironmentVariable を使用する理由:

getenv は、オペレーティング システムによってプロセス用に作成された環境「セグメント」ではなく、ランタイム ライブラリにアクセス可能なデータ構造に対してのみ動作します。したがって、main または wmain に envp 引数を使用するプログラムは、無効な情報を取得する可能性があります。

そしてMSDN GetEnvironment から

この関数は、システム環境変数またはユーザー環境変数のいずれかを取得できます。

于 2009-03-10T18:44:08.520 に答える
11

C++ では std::getenv と#include <cstdlib>

于 2009-03-10T18:39:45.800 に答える
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() が非 constポインターを返すのと同じように、これは悪い習慣につながりやすいのです!

于 2021-01-31T09:00:58.340 に答える