ver variable restaurar por entorno defecto crear c++ wxwidgets boost-filesystem

c++ - restaurar - expandir los nombres de archivos que tienen variables de entorno en su ruta



variables de entorno windows 7 por defecto (9)

¿Cuál es la mejor manera de expandir?

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

o

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

¿Sin atravesar la cadena de ruta buscando variables de entorno directamente? Veo que wxWidgets tiene una función wxExpandEnvVars . No puedo usar wxWidgets en este caso, por lo que esperaba encontrar un impulso: sistema de archivos equivalente o similar. Solo estoy usando el directorio de inicio como ejemplo, estoy buscando una expansión de ruta de propósito general.


Como la pregunta está etiquetada como "wxWidgets", puede usar la función wxExpandEnvVars() que usa wxConfig para la expansión de su variable de entorno. Desafortunadamente, la función en sí no está documentada, pero básicamente hace lo que usted cree que debería y expande cualquier incidencia de $VAR , $(VAR) o ${VAR} en todas las plataformas y también de %VAR% solo en Windows.


Como la pregunta está etiquetada como C ++, puede usar getenv estándar, con un toque de la regex C ++ 11 estándar para reemplazar la variable por su valor.


Dentro del lenguaje C / C ++, esto es lo que hago para resolver las variables de entorno en Unix. El puntero fs_parm contendría la especificación de archivo (o texto) de las posibles variables ambientales que se expandirán. El espacio al que wrkSpc apunta debe tener MAX_PATH + 60 caracteres de longitud. Las comillas dobles en la cadena de eco son para evitar que se procesen los comodines. La mayoría de los shells predeterminados deberían poder manejar esto.

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 */

Para MS Windows, use la función ExpandEnvironmentStrings ().



Esto es lo que yo uso:

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; }


Para sistemas UNIX (o al menos POSIX), eche un vistazo a 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; }

Parece que incluso hará expansiones como glob (que pueden o no ser útiles para su situación particular).


Si tiene el lujo de usar C ++ 11, entonces las expresiones regulares son bastante útiles. Escribí una versión para actualizar en su lugar y una versión declarativa.

#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; }

Una ventaja de este enfoque es que puede adaptarse fácilmente para hacer frente a las variaciones sintácticas y tratar con cadenas anchas también. (Compilado y probado usando Clang en OS X con la bandera -std = c ++ 0x)


Simple y portátil:

#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 ); }

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


Usando Qt, esto funciona para mí:

#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")); cede /home/martin/.myconfigfile (También funciona con expansiones anidadas)