std :: string confronto (controlla se la stringa inizia con un'altra stringa)


90

Devo controllare se una stringa std: inizia con "xyz". Come faccio a farlo senza cercare nell'intera stringa o creare stringhe temporanee con substr ().

Risposte:


164

Userei il metodo di confronto:

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

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

3
Perché non usi semplicemente s.compare (t)?
Franck Mesirard

5
@FranckMesirard: Questo perché per impostazione predefinita il confronto proverebbe a confrontare l'intera lunghezza della stringa passata con i dati del membro e restituirebbe false, mentre fornire la lunghezza come la lunghezza del parametro passato lo farebbe restituire vero (che significa std :: basic_string :: compare , se usato con offset e lunghezza, può essere usato come String.BeginsWith () in altre librerie.) Senza offset e lunghezza, questo non sarebbe vero.
legends2k

1
Restituisce vero se t è vuoto.
gliderkite

14
@gliderkite Come dovrebbe ... la stringa vuota è un prefisso iniziale di ogni stringa.
Jim Balter,

1
Come dovrebbe è corretto ... Se vuoi escludere stringhe vuote: if (! T.empty () &&! S.compare (0, t.length (), t))
ericcurtin

14

Un approccio che potrebbe essere più in linea con lo spirito della libreria standard sarebbe definire il proprio algoritmo begin_with.

#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());
}

Ciò fornisce un'interfaccia più semplice al codice client ed è compatibile con la maggior parte dei contenitori della libreria standard.


Freddo! Questo dovrebbe essere aggiunto per potenziare!
David

2
@David: se il boost è una dipendenza consentita, vedere boost :: algoritmo :: starts_with - predicato 'Starts with'
Gabor

10

Guarda la libreria String Algo di Boost , che ha un numero di funzioni utili, come starts_with, istart_with (senza distinzione tra maiuscole e minuscole), ecc. Se vuoi usare solo una parte delle librerie boost nel tuo progetto, puoi usare l'utility bcp per copiare solo file necessari


4

Sembra che std :: string :: starts_with sia all'interno di C ++ 20, mentre std :: string :: find può essere usato

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

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

1
Questo è molto meglio della risposta accettata usando std::string::compareperché rende facile controllare se la stringa inizia con un letterale senza ripetere il letterale stesso per trovare la sua dimensione. E grazie per aver indicato la soluzione diretta C ++ 20.
Ruslan

Se s1 non inizia con s2, questo proverà comunque ad abbinarlo in seguito, il che non è buono come compare ().
A117

0

Sento di non comprendere appieno la tua domanda. Sembra che dovrebbe essere banale:

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

Questo guarda solo (al massimo) i primi tre caratteri. La generalizzazione di una stringa sconosciuta in fase di compilazione richiederebbe di sostituire quanto sopra con un ciclo:

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

Bene, so come confrontare le stringhe usando le funzioni C. La mia domanda riguardava il farlo in modo orientato agli oggetti tramite C ++ STL.
jackhab

Non vi è alcuna funzione C utilizzata qui. E la Standard Library non ti impedisce di scrivere le tue unzioni.

6
e se t è più corto di s?
vidstige

@jackhab L'autore di STL dice "STL non è orientato agli oggetti. Penso che l'orientamento agli oggetti sia quasi una bufala quanto l'Intelligenza Artificiale". - stlport.org/resources/StepanovUSA.html
Jim Balter,

1
@vidstige Quindi il ciclo termina quando incontra il NUL di terminazione in t.
Jim Balter,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.