std :: string Vergleich (prüfen Sie, ob der String mit einem anderen String beginnt)


90

Ich muss überprüfen, ob ein std: string mit "xyz" beginnt. Wie mache ich das, ohne die gesamte Zeichenfolge zu durchsuchen oder temporäre Zeichenfolgen mit substr () zu erstellen?

Antworten:


164

Ich würde die Vergleichsmethode verwenden:

std::string s("xyzblahblah");
std::string t("xyz")

if (s.compare(0, t.length(), t) == 0)
{
// ok
}

3
Warum benutzt du nicht einfach s.compare (t)?
Franck Mesirard

5
@FranckMesirard: Das liegt daran, dass compare standardmäßig versucht, die gesamte Länge der übergebenen Zeichenfolge mit den Mitgliedsdaten zu vergleichen, und false zurückgibt , während die Angabe der Länge als Länge des übergebenen Parameters dazu führt, dass true zurückgegeben wird (dh std :: basic_string :: vergleichen , wenn sie mit Offset und Länge verwendet werden, kann in anderen Bibliotheken Verwendung wie String.BeginsWith () vorgenommen werden.) Ohne die Offset und Länge, wäre dies nicht wahr sein.
Legends2k

1
Dies gibt true zurück, wenn t leer ist.
Segelflug

14
@gliderkite Wie es sollte ... die leere Zeichenfolge ist ein Anfangspräfix jeder Zeichenfolge.
Jim Balter

1
Wie es richtig sein sollte ... Wenn Sie leere Zeichenfolgen ausschließen möchten: if (! T.empty () &&! S.compare (0, t.length (), t))
ericcurtin

14

Ein Ansatz, der eher dem Geist der Standardbibliothek entspricht, besteht darin, Ihren eigenen Algorithmus "begin_with" zu definieren.

#include <algorithm>
using namespace std;


template<class TContainer>
bool begins_with(const TContainer& input, const TContainer& match)
{
    return input.size() >= match.size()
        && equal(match.begin(), match.end(), input.begin());
}

Dies bietet eine einfachere Schnittstelle zum Clientcode und ist mit den meisten Standardbibliothekscontainern kompatibel.


Cool! Dies sollte hinzugefügt werden, um zu steigern!
David

2
@ David: Wenn Boost eine zulässige Abhängigkeit ist, siehe Boost :: Algorithmus :: Starts_mit - Prädikat 'Beginnt mit'
Gabor

10

Schauen Sie sich die String Algo- Bibliothek von Boost an , die eine Reihe nützlicher Funktionen enthält, z. B. Starts_mit, Istart_with (ohne Berücksichtigung der Groß- und Kleinschreibung) usw. Wenn Sie nur einen Teil der Boost-Bibliotheken in Ihrem Projekt verwenden möchten, können Sie das Dienstprogramm bcp zum Kopieren verwenden nur benötigte Dateien


4

Es scheint, dass sich std :: string :: launch_with in C ++ 20 befindet, während std :: string :: find verwendet werden kann

std::string s1("xyzblahblah");
std::string s2("xyz")

if (s1.find(s2) == 0)
{
   // ok, s1 starts with s2
}

1
Dies ist viel besser als die akzeptierte Antwort, std::string::compareda es einfach ist zu überprüfen, ob die Zeichenfolge mit einem Literal beginnt, ohne das Literal selbst zu wiederholen, um seine Größe zu ermitteln. Und danke, dass Sie auf die direkte C ++ 20-Lösung hingewiesen haben.
Ruslan

Wenn s1 nicht mit s2 beginnt, wird danach immer noch versucht, es abzugleichen, was nicht so gut ist wie compare ().
A117

0

Ich habe das Gefühl, dass ich Ihre Frage nicht vollständig verstehe. Es sieht so aus, als ob es trivial sein sollte:

s[0]=='x' && s[1]=='y' && s[2]=='z'

Dies betrifft nur (höchstens) die ersten drei Zeichen. Die Verallgemeinerung für eine Zeichenfolge, die zur Kompilierungszeit unbekannt ist, würde erfordern, dass Sie die oben genannten durch eine Schleife ersetzen:

// look for t at the start of s
for (int i=0; i<s.length(); i++)
{
  if (s[i]!=t[i])
    return false;
}

Nun, ich weiß, wie man Strings mit C-Funktionen vergleicht. Meine Frage war, ob ich es objektorientiert mit C ++ STL machen soll.
Jackhab

Hier wird keine C-Funktion verwendet. Und die Standardbibliothek hindert Sie nicht daran, eigene Gewerkschaften zu schreiben.

6
und was ist, wenn t kürzer als s ist?
Vidstige

@jackhab Der Autor von STL sagt: "STL ist nicht objektorientiert. Ich denke, dass Objektorientierung fast genauso ein Scherz ist wie künstliche Intelligenz." - stlport.org/resources/StepanovUSA.html
Jim Balter

1
@vidstige Dann endet die Schleife, wenn sie auf das terminierende NUL in trifft t.
Jim Balter
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.