Wie kann ich prüfen, ob eine C++ - std::string beginnt mit einem bestimmten string und konvertiert einen Teilstring in einen int?
Wie implementiere ich die folgenden (Python-pseudocode) in C++?
if argv[1].startswith('--foo='):
foo_value = int(argv[1][len('--foo='):])
(Zum Beispiel, wenn argv[1]
ist --foo=98
, dann foo_value
ist 98
.)
Update: ich bin zögerlich, um zu schauen, in Boost, da bin ich gerade auf der Suche zu machen, eine sehr kleine änderung, um ein einfaches kleines Kommandozeilen-tool (ich würde lieber nicht haben, um zu lernen, wie zu verlinken und die Verwendung von Boost für eine kleine änderung).
- Dieser ist auch interessant.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie bereits mit Boost, die Sie tun können, es mit boost string algorithmen + boost-lexical-cast:
Diese Art von Ansatz, wie viele der anderen Antworten hier ist ok für sehr einfache Aufgaben, aber im langen Lauf Sie sind in der Regel besser über ein command line parsing library. Boost hat ein (Boost.Program_options), was Sinn machen würde, wenn Sie passieren zu sein mit Boost schon.
Sonst eine Suche nach "c++ - Kommandozeilen-parser" wird der Ertrag einer Reihe von Optionen.
Wer braucht noch was? Reine STL!
find
wird nur null sein, wenntiti
ist bei der start string. Wenn es gefunden wird irgendwo sonst, erhalten Sie einen nicht-null-Wert zurückgeben und, wenn es nicht gefunden wird, erhalten Sienpos
ist auch nicht null. Vorausgesetzt ich habe Recht, ich würde es vorziehen, diese Antwort da ich nicht haben, um in einem nicht-standard-Sachen (ja, ich weiß, Boost ist überall, ich würde lieber nur Kern-C++ - libs für einfache Sachen wie diese).titi
, aber die conversion-Teil fehlt.find
wird auch weiterhin auf der Suche, für ein Spiel auch nach es ist schon klar, dass das argument ist nicht ein Präfix zus
. Dies ist eine enorme performance-Einbußen.rfind(s, 0)
haben nicht, dieses problem in den ersten Platz. Ich scheine vergessen zu haben, um es zu löschen. Danke für den Hinweis, wiefind
könnte noch optimiert werden; ich war nicht bewusst, dass die Möglichkeit.Würden Sie es so machen:
Suchen für eine Bibliothek wie Boost.ProgramOptions, dass dies für Sie ist auch eine gute Idee.
atoi("123xyz")
zurück123
, in der Erwägung, dass Python ' sint("123xyz")
eine exception wirft.atoi
mitstrtol
oderstrtoll
werden, die uns erkennen Fehlerbedingungen in der input-Wert.Nur der Vollständigkeit halber erwähne ich das C Weg, es zu tun:
(Zitat von Yasin Rauf hier, markup Hinzugefügt)
Für eine groß- /Kleinschreibung-Vergleich, nutzen
strnicmp
stattstrncmp
.Dies ist das C Weg, es zu tun, für die C++ - strings können Sie verwenden die gleiche Funktion wie diese:
Code, den ich selbst benutze:
substr
führt zu unnötigen kopieren. Diestr.compare(start, count, substr)
Methode verwendet, die in Thomas' Antwort effizienter ist. razvanco13 Antwort hat eine andere Methode, die verhindert das kopieren von mitstd::equal
.atoi
wurde ein C-standard-library-Funktion seit... immer. In der Tatatoi
ist schlecht - nicht, weil es ist Windows-spezifisch ist, sondern weil es (1) C, nicht C++, und (2) veraltet, auch in C (Sie sollten mitstrtol
oder eine der anderen Funktionen. Daatoi
hat keine Fehlerbehandlung. Aber, wieder, das ist nur in C sowieso).Niemand verwendet die STL Algorithmus/mismatch Funktion noch nicht. Wenn diese true zurückgibt, Präfix ist ein Präfix von 'toCheck':
Vollständiges Beispiel prog:
Edit:
Als @James T. Huggett schlägt vor, std::equal ist eine bessere Passform für die Frage: Ist Ein Präfix von B? und ist leicht kürzer-code:
Vollständiges Beispiel prog:
std::equal
für strings hat den Nachteil, dass es nicht erkennt die Zeichenfolge am Ende, so müssen Sie manuell überprüfen, ob das Präfix ist kürzer als der ganze string. (Als richtig gemacht in der Beispiel-prog, aber fehlt in der one-liner oben).Gegeben, dass beide Zeichenfolgen —
argv[1]
und"--foo"
— sind C-strings, @FelixDombek Antwort ist die Hände-down die beste Lösung.Sehen die anderen Antworten, aber ich dachte es erwähnenswert, dass, wenn Ihr text bereits als ein
std::string
, dann eine einfache, null-Kopie, die maximal effiziente Lösung existiert, die noch nicht erwähnt wurde bisher:Und wenn foo bereits ein string:
rfind(x, 0) == 0
sollte wirklich in der Norm definiert alsstarts_with
rfind()
(stattstartswith()
) ist sehr ineffizient - es hält auf der Suche, bis das Ende der Zeichenfolge.Verwendung von STL-dies Aussehen könnte:
if (prefix.size()<=arg.size() && std::equal(...))
.Auf die Gefahr geflamed zu werden für die Verwendung von C-Konstrukten, ich denke, das
sscanf
Beispiel ist eleganter als die meisten Boost-Lösungen. Und Sie müssen nicht sorgen zu machen über die Verknüpfung, wenn Sie überall, dass hat einen Python-interpreter!Hier einige Beispiel-Ausgabe zeigt, dass die Lösung verarbeitet leading/trailing garbage als richtig, wie die entsprechenden Python-code, und mehr richtig, als alles, was mit
atoi
(die fälschlicherweise ignorieren eine nicht-numerische suffix).argv[i]
ist"--foo=9999999999999999999999999"
, das Verhalten ist nicht definiert, (obwohl die meisten oder alle Implementierungen Verhalten sollte sanely). Ich gehe davon aus9999999999999999999999999 > INT_MAX
.if (one-liner)
Mit C++17, die Sie verwenden können
std::basic_string_view
& mit C++20std::basic_string::starts_with
oderstd::basic_string_view::starts_with
.Nutzen
std::string_view
im Vergleich zustd::string
- in Bezug auf Speicher-management - ist, dass es hält nur ein Zeiger auf einen "string" (zusammenhängende Sequenz von char-ähnlichen Objekte) und kennt seine Größe. Beispiel ohne verschieben/kopieren die Quell-strings, nur um mit den integer-Wert:Benutze ich
std::string::compare
verpackt in utility-Methode wie folgt:Warum nicht gnu getopts? Hier ist ein einfaches Beispiel (ohne Sicherheitsprüfung):
Für den folgenden Befehl ein:
Erhalten Sie
In Fall müssen Sie die C++11-Kompatibilität und nicht die Verwendung von boost, hier ist eine boost-kompatibel drop-in mit einem Beispiel der Nutzung:
Können Sie auch
strstr
:aber ich denke, es ist nur gut für kurze strings, da hat es eine Schleife über den gesamten string, wenn der string nicht tatsächlich beginnen mit 'substr'.
Ok, warum die komplizierte Nutzung von Bibliotheken und Sachen? C++ String-Objekte überladen des [] - operator, so können Sie einfach vergleichen chars.. Wie das, was ich gerade getan habe, weil ich will, um eine Liste aller Dateien in einem Verzeichnis und ignoriert die unsichtbaren Dateien und .. und . pseudofiles.
So einfach ist das..
Seit C++11 auch std::regex_search verwendet werden kann, z.B. wie folgt (eine leere Zeichenfolge zurück, im Fehlerfall):
Mit C++11 oder höher können Sie
find()
undfind_first_of()
Beispiel für die Verwendung finden, um einen einzigen char:
Beispiel für die Verwendung finden, zu finden, eine vollständige Zeichenfolge & ab der position 5:
Beispiel für die Verwendung der
find_first_of()
und nur den ersten char zu suchen, der am Anfang nur:Glück!
Dies ist völlig ungetestet. Das Prinzip ist das gleiche wie der Python-Version. Erfordert Steigern.StringAlgo und zu Steigern.LexicalCast.
Prüfen, ob der string beginnt mit der anderen Schnur, und dann Holen Sie sich die substring ('slice') des ersten string ein und wandeln es mithilfe von lexikalischen Besetzung.