Ich habe einen std :: string, der einen Befehl enthält, der mit execv ausgeführt werden kann, was ist der beste "C ++" Weg, um ihn in den "char * argv []" zu konvertieren, der vom zweiten Parameter von execv () benötigt wird ?
Zur Klarstellung:
%Vor% Natürlich funktioniert das nicht mit Commans, die Zitate wie rm "a file.mp3"
verwenden. Sie können die POSIX-Funktion wordexp
in Betracht ziehen, die das interessiert, und vieles mehr.
Sehr unixy Antworten hier. Was ist los mit:
%Vor%Warum sollten Sie einen Befehlszeilen-Parser schreiben, wenn es schon einen guten auf dem System gibt?
(Hinweis: Ein guter Grund ist, dass Sie dem String, den Sie ausführen wollen, nicht vertrauen. Man hofft, dass dies bereits zutrifft, aber die Shell wird "mehr" mit diesem String machen als ein naive Whitespace-Splitter wird und damit mehr Sicherheitslücken öffnen, wenn Sie nicht vorsichtig sind.)
Eine Kombination aus der String-Methode c_str () und strtok (), um sie durch Leerzeichen aufzuteilen, sollte Ihnen das Array von Strings liefern, die Sie an exec () und die zugehörigen Funktionen übergeben müssen.
Vielleicht split_winmain
von Boost.ProgramOptions. Boost ist in den meisten Fällen eine gute Wahl.
Ссылка
Wenn Sie nur an Windows interessiert sind (andere Kernel kennen normalerweise keine Befehlszeilen im Windows-Sinne), können Sie die API-Funktion CommandLineToArgvW
verwenden, die die gleichen Konventionen wie die MS C-Laufzeit verwendet.
Im Allgemeinen hängt es vom Zitatstil der Plattform und / oder der Shell ab. Die Microsoft C Runtime verwendet einen ganz anderen Stil als z. Bash!
Okay, ich bin schon oft genug darüber gestolpert. Dies ist ein gerades "C", so dass es entweder in C oder C ++ gesteckt werden kann. Es behandelt einzelne und doppelte Anführungszeichenfolgen unterschiedlich. Der Aufrufer ist für die Zuordnung von argv [0] (wenn nicht NULL) und argv.
verantwortlich %Vor%Dies ist eine Variation von litbs Antwort, aber ohne die gesamte manuelle Speicherzuweisung. Es wird immer noch nicht mit Zitaten umgehen.
%Vor%Ich fühle mich irgendwie schmutzig über die const_cast & lt; & gt ;, aber Programme sollten wirklich nicht den Inhalt der Argv-Strings verändern.
Sie können die Funktion c_str () von std :: string verwenden, um sie in char * umzuwandeln. Die strtok-Funktion teilt die Zeichenfolge mit dem Trennzeichen.
Matt Peitreks LIBTINYC hat ein Modul namens argcargv.cpp, das eine Zeichenkette entgegennimmt und sie zum Array des Arguments analysiert zitierte Argumente berücksichtigen. Beachten Sie, dass es Windows-spezifisch ist, aber es ist ziemlich einfach, daher sollte es einfach sein, auf die von Ihnen gewünschte Plattform zu wechseln.
Wenn Sie das tun, ändern Sie es auch, um als Parameter die Position zu nehmen, um den Zählwert und den a-Zeiger auf das argv-Array zu setzen, anstatt extern zu verwenden (nur mein kleiner Ratschlag). Matt brauchte das nicht, weil LIBTINYC die Laufzeit war.
Alternativ können Sie in der Laufzeitquelle Ihres Compilers nachsehen (was fast alles bietet), um zu sehen, was sie tun, um die Befehlszeile zu analysieren und entweder direkt aufzurufen (wenn dies sich als praktikabel erweist) oder die Ideen von diesem Bit zu entlehnen Code.
Vielleicht ist es zu spät, um auf diese Frage zu antworten, aber Sie könnten Standart-POSIX-Funktionen verwenden glob oder wordexp :
%Vor% Es würde drei Parameter vorbereiten: -l
(langes Listenformat), -t
(nach Änderungszeit sortieren) und Verzeichnis /etc
, um aufzulisten, und /bin/ls
ausführen. Aufruf wordexp()
gibt Ihnen genau das gleiche Ergebnis wie der Aufruf /bin/sh -c
zuvor empfohlen, aber der gespawnte Prozess hätte den übergeordneten Prozess nicht /bin/sh
.