28

展開する最良の方法は何ですか

${MyPath}/filename.txt to /home/user/filename.txt

また

%MyPath%/filename.txt to c:\Documents and settings\user\filename.txt

パス文字列をたどらずに環境変数を直接探しますか? wxWidgets にwxExpandEnvVars関数があることがわかりました。この場合、wxWidgets を使用できないので、boost::filesystem と同等または類似のものを見つけたいと思っていました。例としてホーム ディレクトリのみを使用しています。汎用のパス展開を探しています。

4

8 に答える 8

31

UNIX (または少なくとも POSIX) システムの場合は、wordexpを参照してください。

#include <iostream>
#include <wordexp.h>
using namespace std;
int main() {
  wordexp_t p;
  char** w;
  wordexp( "$HOME/bin", &p, 0 );
  w = p.we_wordv;
  for (size_t i=0; i<p.we_wordc;i++ ) cout << w[i] << endl;
  wordfree( &p );
  return 0;
}

グロブのような展開も行うようです(特定の状況では役立つ場合とそうでない場合があります)。

于 2010-12-07T10:17:16.823 に答える
22

Windows では、 を使用できますExpandEnvironmentStrings。Unix に相当するものについてはまだわかりません。

于 2009-12-14T19:03:09.470 に答える
18

C++11 を使用する余裕がある場合は、正規表現が非常に便利です。その場で更新するためのバージョンと宣言的なバージョンを作成しました。

#include <string>
#include <regex>

// Update the input string.
void autoExpandEnvironmentVariables( std::string & text ) {
    static std::regex env( "\\$\\{([^}]+)\\}" );
    std::smatch match;
    while ( std::regex_search( text, match, env ) ) {
        const char * s = getenv( match[1].str().c_str() );
        const std::string var( s == NULL ? "" : s );
        text.replace( match[0].first, match[0].second, var );
    }
}

// Leave input alone and return new string.
std::string expandEnvironmentVariables( const std::string & input ) {
    std::string text = input;
    autoExpandEnvironmentVariables( text );
    return text;
}

このアプローチの利点は、構文のバリエーションに対処し、幅の広い文字列を処理するために簡単に適応できることです。(フラグ -std=c++0x を指定して OS X で Clang を使用してコンパイルおよびテスト済み)

于 2014-05-03T09:45:42.653 に答える
3

質問には「wxWidgets」というタグが付けられているため、環境変数の展開にwxConfigwxExpandEnvVars()で使用される関数を使用できます。関数自体は残念ながら文書化されていませんが、基本的には、必要と思われることを実行し、すべてのプラットフォームで、またはWindows のみで出現する 、または を展開します。$VAR$(VAR)${VAR}%VAR%

于 2013-02-16T23:25:50.300 に答える
2

C/C++ 言語内で、Unix で環境変数を解決するために私が行っていることを次に示します。fs_parm ポインターには、展開される可能性のある環境変数のファイル仕様 (またはテキスト) が含まれます。wrkSpc が指すスペースは、MAX_PATH+60 文字の長さでなければなりません。エコー文字列の二重引用符は、ワイルド カードが処理されないようにするためのものです。ほとんどのデフォルト シェルは、これを処理できるはずです。


   FILE *fp1;

   sprintf(wrkSpc, "echo \"%s\" 2>/dev/null", fs_parm);
   if ((fp1 = popen(wrkSpc, "r")) == NULL || /* do echo cmd     */
       fgets(wrkSpc, MAX_NAME, fp1) == NULL)/* Get echo results */
   {                        /* open/get pipe failed             */
     pclose(fp1);           /* close pipe                       */
     return (P_ERROR);      /* pipe function failed             */
   }
   pclose(fp1);             /* close pipe                       */
   wrkSpc[strlen(wrkSpc)-1] = '\0';/* remove newline            */

MS Windows の場合、ExpandEnvironmentStrings() 関数を使用します。

于 2011-01-02T22:04:12.757 に答える
1

これは私が使用するものです:

const unsigned short expandEnvVars(std::string& original)
{
    const boost::regex envscan("%([0-9A-Za-z\\/]*)%");
    const boost::sregex_iterator end;
    typedef std::list<std::tuple<const std::string,const std::string>> t2StrLst;
    t2StrLst replacements;
    for (boost::sregex_iterator rit(original.begin(), original.end(), envscan); rit != end; ++rit)
        replacements.push_back(std::make_pair((*rit)[0],(*rit)[1]));
    unsigned short cnt = 0;
    for (t2StrLst::const_iterator lit = replacements.begin(); lit != replacements.end(); ++lit)
    {
        const char* expanded = std::getenv(std::get<1>(*lit).c_str());
        if (expanded == NULL)
            continue;
        boost::replace_all(original, std::get<0>(*lit), expanded);
        cnt++;
    }
    return cnt;
}
于 2013-02-16T15:12:16.437 に答える
0

Qtを使用すると、これは私にとってはうまくいきます:

#include <QString>
#include <QRegExp>

QString expand_environment_variables( QString s )
{
    QString r(s);
    QRegExp env_var("\\$([A-Za-z0-9_]+)");
    int i;

    while((i = env_var.indexIn(r)) != -1) {
        QByteArray value(qgetenv(env_var.cap(1).toLatin1().data()));
        if(value.size() > 0) {
            r.remove(i, env_var.matchedLength());
            r.insert(i, value);
        } else
            break;
    }
    return r;
}

expand_environment_variables(QString("$HOME/.myconfigfile")); /home/martin/.myconfigfile を生成します (ネストされた展開でも動作します)

于 2014-03-19T13:25:46.340 に答える