展开其路径中包含环境变量的文件名

Dan*_*Dan 22 c++ wxwidgets boost-filesystem

什么是扩展的最佳方式

${MyPath}/filename.txt to /home/user/filename.txt
Run Code Online (Sandbox Code Playgroud)

要么

%MyPath%/filename.txt to c:\Documents and settings\user\filename.txt
Run Code Online (Sandbox Code Playgroud)

遍历遍历路径字符串直接寻找环境变量?我看到wxWidgets有一个wxExpandEnvVars函数.在这种情况下我不能使用wxWidgets,所以我希望找到一个boost :: filesystem等价或类似的.我只使用主目录作为示例,我正在寻找通用路径扩展.

Mik*_*eGM 25

对于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;
}
Run Code Online (Sandbox Code Playgroud)

它似乎甚至会做类似于全球的扩展(对你的特定情况可能有用也可能没用).

  • 如果可以的话,我将投票3次。使用系统提供的工具的很好的答案,它肯定比正则表达式更容易出错。 (2认同)

Rob*_*edy 18

在Windows上,您可以使用ExpandEnvironmentStrings.还不确定Unix等价物.


sfk*_*ach 9

如果你有使用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;
}
Run Code Online (Sandbox Code Playgroud)

这种方法的一个优点是它可以很容易地适应语法变化并处理宽字符串.(在OS X上使用Clang进行编译和测试,标志为-std = c ++ 0x)

  • g++ 4.9.3 (Ubuntu) 无法编译,这与 iterator 和 const_iterator 之间的转换有关。我必须改变 text.replace( match[0].first, match[0].second, var ); 到 text.replace( match.position(0), match.length(0), var ); (3认同)

小智 6

简单便携:

#include <cstdlib>
#include <string>

static std::string expand_environment_variables( const std::string &s ) {
    if( s.find( "${" ) == std::string::npos ) return s;

    std::string pre  = s.substr( 0, s.find( "${" ) );
    std::string post = s.substr( s.find( "${" ) + 2 );

    if( post.find( '}' ) == std::string::npos ) return s;

    std::string variable = post.substr( 0, post.find( '}' ) );
    std::string value    = "";

    post = post.substr( post.find( '}' ) + 1 );

    const *v = getenv( variable.c_str() );
    if( v != NULL ) value = std::string( v );

    return expand_environment_variables( pre + value + post );
}
Run Code Online (Sandbox Code Playgroud)

expand_environment_variables( "${HOME}/.myconfigfile" ); 产量 /home/joe/.myconfigfile

  • const* v 之后缺少“char” (2认同)