C'è qualche modo in C++ per verificare se una stringa inizia con una certa stringa (più piccola dell'originale)? Proprio come possiamo fare in Javacome verificare l'inizio della stringa in C++
bigString.startswith(smallString);
C'è qualche modo in C++ per verificare se una stringa inizia con una certa stringa (più piccola dell'originale)? Proprio come possiamo fare in Javacome verificare l'inizio della stringa in C++
bigString.startswith(smallString);
std::string s("Hello world");
if (s.find("Hello") == 0)
{
std::cout << "String starts with Hello\n";
}
@avakar Sono d'accordo. Non ho ancora provato le espressioni regolari di C++ 11, ma sarebbe anche una soluzione e, si spera, più efficiente? –
Penso che regex sia una cattiva scelta per un controllo così semplice, vedere la mia risposta per quello che penso sia una soluzione efficiente per questo problema. O ancora meglio, Alan Stokes risponde con string :: compare(). – Kleist
Una soluzione efficiente dovrebbe essere 'O (min (bigString.length(), smallString.length()))' –
Gli approcci utilizzando string::find()
o string::substr()
non sono ottimali perché sia fare una copia della stringa, o la ricerca di più di partite all'inizio della stringa. Potrebbe non essere un problema nel tuo caso, ma se è possibile utilizzare l'algoritmo std::equal
. Ricordati di controllare che il "pagliaio" sia lungo almeno quanto "l'ago".
#include <string>
using namespace std;
bool startsWith(const string& haystack, const string& needle) {
return needle.length() <= haystack.length()
&& equal(needle.begin(), needle.end(), haystack.begin());
}
O creare una stringa che è la lunghezza della variabile smallString
, e confrontare i due. Oppure effettuare una ricerca per la sottostringa smallString
e vedere se restituisce l'indice 0
strstr()
restituisce un puntatore alla prima occorrenza di una stringa all'interno di una stringa.
http://www.cplusplus.com/reference/string/string/substr/
È possibile utilizzare String.substr() per vedere qualsiasi numero di caratteri da qualsiasi posizione, o si potrebbe utilizzare un membro string.find().
È possibile eseguire questa operazione con string::compare()
, che offre varie opzioni per il confronto di tutte o parte di due stringhe. Questa versione confronta smallString
con il prefisso dimensione appropriata di bigString
(e funziona correttamente se bigString
è più breve di smallString
):
bigString.compare(0, smallString.length(), smallString) == 0
tendo a avvolgere questo in una funzione gratuita chiamata startsWith()
, poiché in caso contrario si può guardare un po ' misterioso.
UPDATE: C++20 is adding nuova starts_with
e ends_with
funzioni, in modo sarete finalmente in grado di scrivere solo bigString.starts_with(smallString)
.
La soluzione corretta, come sempre, proviene da Boost: boost::algorithm::starts_with
.
Awful da usare boost solo per fare questo semplice compito. – Borzh
@Borzh, sicuramente stai già utilizzando Boost pesantemente nei tuoi progetti, perché no per questo? – avakar
Non tutti usano boost. E per scaricarlo, metterlo nel repository solo per usare starts_with() è un po 'esagerato. Forse dovresti considerare di rimuovere "La soluzione corretta, come sempre ...". Non è né "corretto" né "sempre". – Borzh
L'approccio più semplice potrebbe essere:
if (smallString.size() <= bigString.size()
&& std::equals(smallString.begin(), smallString.end(), bigString.end())
(Questo funziona anche se uno dei due, o entrambi, è un vettore O qualsiasi altro tipo container standard..)
-1 1) Non riesco a trovare nessuno std :: equals. Intendevi: std :: uguale? 2) sei sicuro con bigString.end() - ci si aspetterebbe bigString.begin()? 3) risposta di Kleist postata prima sembra di avere tutto a posto – Suma
Sì, ad entrambi. È 'std :: equal', e dovrebbe essere' bigString.end() '. –
Per ottimizzare un po ':
if (smallString.size() <= bigString.size() &&
strncmp(smallString.c_str(), bigString.c_str(), smallString.length()) == 0)
non dimenticare di #include <cstring>
o #include <string.h>
Ho pensato che pubblicare una soluzione grezza che non utilizza alcuna funzione di libreria ...
// Checks whether `str' starts with `start'
bool startsWith(const std::string& str, const std::string& start) {
if (&start == &str) return true; // str and start are the same string
if (start.length() > str.length()) return false;
for (size_t i = 0; i < start.length(); ++i) {
if (start[i] != str[i]) return false;
}
return true;
}
Aggiunta di un semplice std::tolower
possiamo fare questo case insensitive
// Checks whether `str' starts with `start' ignoring case
bool startsWithIgnoreCase(const std::string& str, const std::string& start) {
if (&start == &str) return true; // str and start are the same string
if (start.length() > str.length()) return false;
for (size_t i = 0; i < start.length(); ++i) {
if (std::tolower(start[i]) != std::tolower(str[i])) return false;
}
return true;
}
Mi sorprende che nessuno ha scritto ancora questo metodo:
#include <string>
using namespace std;
bool starts_with(const string& smaller_string, const string& bigger_string)
{
return (smaller_string == bigger_string.substr(0,smaller_string.length()));
}
stai parlando stringhe C o std: : String –
sto parlando di C++ string.std :: string –