convertit une chaîne de argv en c++
J'ai un std::string contenant une commande à exécuter avec execv, quel est le meilleur "C++" façon de convertir le "char *argv[]" qui est requise par le second paramètre de la fonction execv()?
À préciser:
std::string cmd = "mycommand arg1 arg2";
char *cmd_argv[];
StrToArgv(cmd, cmd_argv); //how do I write this function?
execv(cmd_argv[0], cmd_argv);
OriginalL'auteur aaronstacy | 2009-10-02
Vous devez vous connecter pour publier un commentaire.
Bien sûr, cela ne fonctionne pas avec commans qui utilisent citant comme
rm "a file.mp3"
. Vous pouvez envisager de la fonction POSIXwordexp
qui se soucie de cela et beaucoup plus.vrai, sans doute, à un certain moment dans le programme, il avait déjà les arguments dans un tableau - nous ne savons pas. Mais si il vient d'une chaîne, et qu'il doit faire quelque chose comme le fractionnement, pour certaines fins comme l'exploitation forestière ou de la vérification, il est toujours utile de connaître les
wordexp
etc. Je suis d'accord qu'en général, tout en poussant àsh
est une bonne idée.OriginalL'auteur Johannes Schaub - litb
Très non-unixy réponses ici. Quel est le problème avec:
Pourquoi s'embêter à écrire une ligne de commande analyseur quand il y a un parfaitement bon déjà sur le système?
(Note: une bonne raison est parce que vous ne faites pas confiance à la chaîne que vous êtes sur le point de s'exécuter. On espère que c'est déjà le cas, mais le shell va faire "plus" de cette chaîne qu'un naïf blanc, séparateur et ainsi ouvrir de plus en plus de failles de sécurité si vous n'êtes pas prudent.)
Un système avec le système execve() de l'appel système, mais pas de shell? Jamais entendu parler d'une telle bête.
quand je lance un programme de test avec les deux lignes ci-dessus, et cmd = "echo hello world", le execl appel n'aboutit pas, il renvoie. Le errno est 2. lorsque je modifie le premier argument de la "sh" de "/bin/sh", il me donne l'erreur "-c: echo bonjour tout le monde: Aucun fichier ou répertoire"
En effet, ma réponse a été tapé sans tester. Le premier argument doit être le nom de la commande, correspondant à argv[0], pas le premier argument en lui-même.
OriginalL'auteur Andy Ross
Une combinaison de la c_str() méthode de chaîne et de strtok() pour le séparer par des espaces devrait vous obtenez le tableau de chaînes de caractères, vous devez passer à exec() et de ses fonctions.
Eh bien, oui, vous devez être prudent. La citation est une toute nouvelle boîte de pandore.
OriginalL'auteur Carl Norum
Peut-être
split_winmain
de Boost.ProgramOptions. Boost est un bon choix dans la plupart des cas.http://www.boost.org/doc/libs/1_40_0/doc/html/program_options/howto.html#id1396212
Si vous êtes uniquement intéressé par Windows (les autres ne savent généralement pas sur des lignes de commande dans Windows sens), vous pouvez utiliser la fonction API
CommandLineToArgvW
qui utilise les mêmes conventions que la MS C runtime.En général, il dépend de la citant le style de la plate-forme et/ou de l'environnement. Microsoft C Runtime utilise un style un peu différent que, par exemple, bash!
OriginalL'auteur Philipp
OK, j'ai été achoppement sur moi-même assez de temps. Il s'agit de droite "C", de sorte qu'il peut être branché soit en C ou C++. Il traite de simple et double quote chaînes de la même façon. L'appelant est responsable de la désallocation de argv[0] (si non NULL) et argv.
OriginalL'auteur Bruce
C'est une variation sur litb réponse, mais sans le manuel d'allocation de mémoire. Il ne gère pas le citer.
Je me sens un peu sale sur le const_cast<>, mais les programmes ne devrait pas modifier le contenu de la argv chaînes.
v1
pousse, tous les pointeurs dansv2
peut être invalidé.merci, changé pour une liste.
OriginalL'auteur Brian Neal
Vous pouvez utiliser le c_str() la fonction de std::string pour convertir en char*.
La fonction strtok se partageront la chaîne à l'aide de la ' délimiteur.
execv
. Il requiert des arguments à transmettre comme des éléments distincts dans le tableau.Ouais c'est vrai. Je n'ai pas le code d'exemple lors de la rédaction de la réponse.
OriginalL'auteur Patrice Bernassola
Matt Peitrek de LIBTINYC a un module appelé argcargv.cpp qui prend une chaîne et l'analyse à l'argument de la matrice de prendre cité arguments en compte. Notez qu'il est spécifique à Windows, mais c'est assez simple devrait donc être facile de se déplacer à quelle que soit la plateforme que vous voulez.
Si vous le faites, aussi de le modifier pour prendre en tant que paramètres de l'emplacement pour mettre le comte et le pointeur vers le tableau argv au lieu d'utiliser des externes (juste mon petit conseil). Matt n'avait pas besoin qu'car LIBTINYC était le moment de l'exécution.
Alternativement, vous pouvez regarder dans votre compilateur de l'exécution de la source (presque tous les fournir) pour voir ce qu'ils font pour analyser la ligne de commande, soit appeler directement (si cela s'avère être réalisable) ou d'emprunter les idées de ce bout de code.
OriginalL'auteur Michael Burr
Peut-être que c'est trop tard pour répondre à cette question, mais vous pouvez utiliser le standart fonctions POSIX glob ou wordexp:
Il établirait à 3 paramètres:
-l
(long format de liste),-t
(tri par date de modification) et le répertoire/etc
à la liste, et d'exécuter/bin/ls
. Appelwordexp()
vous donne exactement le même résultat que l'appel de/bin/sh -c
recommandé précédemment mais spawaned processus aurait processus parent ne/bin/sh
.OriginalL'auteur linker
Comme il s'est avéré une fonction existe quelque peu caché dans le programme boost options pour cela.
Le split_unix() fonctionne avec échappé et a cité les lignes de commande.
OriginalL'auteur tkarls