Betrachten Sie eine weitere Implementierung. Ausführen.
#include // für isspace()
/**
* Trennen Sie das nächste nicht-leere Wort aus einem String heraus.
* @note Kein nullptr-Schutz
* @param str [IN] Zeiger auf Zeiger auf den String. Verschachtelter Zeiger auf String wird geändert.
* @param word [OUT] Zeiger auf den Zeiger des nächsten Wortes. Zum Ausfüllen.
* @return Zeiger auf Zeichenfolge - aktueller Cursor. Überprüfen Sie darauf, ob '\0' aufgerufen werden soll anhalten diese Funktion
*/
static char* splitArgv(char **str, char **word)
{
constexpr char QUOTE = '\'';
bool inquotes = false;
// Optimierung
if( **str == 0 )
return NULL;
// Führende Leerzeichen überspringen.
while (**str && isspace(**str))
(*str)++;
if( **str == '\0')
return NULL;
// Satz in Anführungszeichen ist ein Argument
if( **str == QUOTE ){
(*str)++;
inquotes = true;
}
// Setzen Sie den Satzanfang
*word = *str;
// Alle Zeichen überspringen, wenn in Anführungszeichen
if( inquotes ){
while( **str && **str!=QUOTE )
(*str)++;
//if( **str!= QUOTE )
}else{
// Überspringen von Nicht-Leerzeichenzeichen.
while( **str && !isspace(**str) )
(*str)++;
}
// Satz nullterminieren und den `str`-Zeiger auf das nächste Symbol setzen
if(**str)
*(*str)++ = '\0';
return *str;
}
/// Um die Standardkonvention zu unterstützen wird `argv[argc]` auf `NULL` gesetzt
///\param[IN] str : Eingabestring. Wird geändert - in Teilzeichenfolgen aufgeteilt
///\param[IN] argc_MAX : Maximales a rgc, mit anderen Worten Größe des Eingabearrays \p argv
///\param[OUT] argc : Anzahl der auszufüllenden Argumente
///\param[OUT] argv : Array von Zeigern auf C-Zeichenfolgen, die ausgefüllt werden sollen. All diese Zeichenfolgen sind Teilzeichenfolgen von \p str
///\return Zeiger auf den Rest des Strings. Überprüfen Sie, ob er '\0' und wissen Sie, ob noch etwas analysiert werden soll. \
/// Wenn das Ergebnis !='\0' ist, ist \p argc_MAX zu klein, um alles zu analysieren.
char* parseStrToArgcArgvInsitu( char *str, const int argc_MAX, int *argc, char* argv[] )
{
*argc = 0;
while( *argc
``### Nutzungscode
#include
using namespace std;
void parseAndPrintOneString(char *input)
{
constexpr size_t argc_MAX = 5;
char* v[argc_MAX] = {0};
int c=0;
char* rest = parseStrToArgcArgvInsitu(input,argc_MAX,&c,v);
if( *rest!='\0' ) // oder klarer `strlen(rest)==0` aber nicht effizient
cout<<"Es gibt noch etwas zu analysieren. argc_MAX ist zu klein."<
`### Ausgabe:
Zeile analysieren "Just another TEST\r\n":
argc : 3
argv[0] : Just
argv[1] : another
argv[2] : TEST
Zeile analysieren " Hello my world 'in quotes' !":
Es gibt noch etwas zu analysieren. argc_MAX ist zu klein.
argc : 4
argv[0] : Hello
argv[1] : my
argv[2] : world
argv[3] : in quotes
Zeile analysieren "./hi 'Less is more'":
argc : 2
argv[0] : ./hi
argv[1] : Less is more
Zeile analysieren "Very long line with "double quotes" should be parsed several times if argv[] buffer is small":
Es gibt noch etwas zu analysieren. argc_MAX ist zu klein.
argc : 4
argv[0] : Very
argv[1] : long
argv[2] : line
argv[3] : with
Zeile analysieren "
":
argc : 0` ``
0 Stimmen
Für welche Plattform? Wie Befehlszeilen in argc/argv umgewandelt werden, unterscheidet sich erheblich zwischen Windows und UNIX-basierten Systemen, zum Beispiel. Auf UNIX transformiert die Shell in der Regel die Befehlszeile erheblich, einschließlich des Durchlaufens (Dateimustererweiterung) und der Variablensubstitution. Auf Windows wird die Dateimustererweiterung nicht von der Shell durchgeführt (es sei denn, Sie verwenden etwas wie Cygwin oder das MKS Toolkit).
0 Stimmen
Wenn Sie nicht einmal mit zitierten Argumenten umgehen müssen, würde ich wirklich vorschlagen, Ihre eigene Funktion zu codieren, anstatt eine Bibliothek von Drittanbietern nur für diese Aufgabe einzuführen.
2 Stimmen
Hast du getopt() ausprobiert? (man 3 getopt). Du kannst die Quellen für die meisten Standard-UNIX/Linux-Tools für Beispiele einsehen, eine RIESIGE Anzahl davon. Selbst die Man-Page (zumindest die Linux-Version) enthält ein ordentliches Beispiel. Es gibt auch eine Reihe von Wrapper-Funktionen (du siehst hier Empfehlungen), aber getopt() scheint die einzige verfügbare für JEDE UNIX-Plattform zu sein (tatsächlich scheint sie Teil des POSIX-Standards zu sein).
0 Stimmen
Wenn Sie immer noch interessiert sind und industrielle Stärke von Grund auf wollen, in einem kleinen Codepaket. Suchen Sie auf dieser Seite nach
nargv
Mit Abstand die beste Lösung, die ich hier aus reinem c-Code gesehen habe. Bitte stimmen Sie für diese Antwort! Damit andere sie finden können.0 Stimmen
@user735796 Ich habe nach
nargv
gesucht und dein Kommentar ist der einzige Treffer. Also habe ich gegoogelt: github.com/hypersoft/nargv ... Ein paar Anmerkungen jedoch. Dies verwendet C99, daher wird es nicht mit dem Microsoft C-Compiler funktionieren. Auch eine Idee ist es, Unit-Tests mit einer Vielzahl von Testfällen zu haben, die jeden Typ von Szenario für den Parser überprüfen, um sicherzustellen, dass es wie erwartet funktioniert.0 Stimmen
Für Unix-Entwickler, die eine sehr einfache, aber leistungsstarke Implementierung wünschen, die das Bash-Style Escaping und Quoting behandelt: github.com/pasztorpisti/cmd2argv
0 Stimmen
Du möchtest wahrscheinlich auch das Globbing aktivieren, also siehe glob(7) und folge den dortigen Verweisen.
0 Stimmen
Nicht sicher, warum getopt hier Upvotes bekommt --- es löst ein anderes Problem (Analyse des Inhalts eines argv-Arrays, anstatt tatsächlich ein argv-Array aus einem String zu erstellen, wonach der OP gefragt hat).
0 Stimmen
Schau dir das an: stackoverflow.com/a/54617539/236062