55 votes

Vérifier si une chaîne de caractères est le préfixe d'une autre.

J'ai deux cordes que j'aimerais comparer : String et String: . Existe-t-il une fonction de bibliothèque qui renverrait un message vrai lorsqu'on lui passe ces deux chaînes de caractères, mais faux pour, par exemple String et OtherString ?

Pour être précis, je veux savoir si une chaîne est le préfixe d'une autre.

2 votes

Et si on utilisait le bon vieux string.compare() ?

0 votes

Vous voulez dire comparer les N premiers personnages ?

0 votes

@Donotalo Ce serait bien, ce serait bien s'il le faisait pour moi afin que je n'aie pas besoin de faire de la musculation. n .

5voto

Frerich Raabe Points 23711

Si vous pouvez raisonnablement ignorer tout codage multi-octet (par exemple, UTF-8), alors vous pouvez utiliser strncmp pour ça :

// Yields true if the string 's' starts with the string 't'.
bool startsWith( const std::string &s, const std::string &t )
{
    return strncmp( s.c_str(), t.c_str(), t.size() ) == 0;
}

Si vous tenez à utiliser une version fantaisiste de C++, vous pouvez utiliser la fonction std::equal (avec l'avantage supplémentaire que votre fonction fonctionne également pour d'autres collections, et pas seulement pour les chaînes de caractères) :

// Yields true if the string 's' starts with the string 't'.
template <class T>
bool startsWith( const T &s, const T &t )
{
    return s.size() >= t.size() &&
           std::equal( t.begin(), t.end(), s.begin() );
}

5voto

RongyanZheng Points 129

Après C++20, nous pouvons utiliser commence_avec pour vérifier si une chaîne de caractères commence par un préfixe donné.

str.starts_with(prefix)

Il y a aussi avec pour vérifier le suffixe

4voto

Flexo Points 39273

Pourquoi pas simplement :

bool prefix(const std::string& a, const std::string& b) {
  if (a.size() > b.size()) {
    return a.substr(0,b.size()) == b;
  }
  else {
    return b.substr(0,a.size()) == a;
  }
}

C++ pas C, sûr, simple, efficace.

Testé avec :

#include <string>
#include <iostream>

bool prefix(const std::string& a, const std::string& b);

int main() {
  const std::string t1 = "test";
  const std::string t2 = "testing";
  const std::string t3 = "hello";
  const std::string t4 = "hello world";
  std::cout << prefix(t1,t2) << "," << prefix(t2,t1) << std::endl;
  std::cout << prefix(t3,t4) << "," << prefix(t4,t3) << std::endl;
  std::cout << prefix(t1,t4) << "," << prefix(t4,t1) << std::endl;
  std::cout << prefix(t1,t3) << "," << prefix(t3,t1) << std::endl;

}

Si vous avez C++17, vous pouvez écrire une meilleure version de ceci, en utilisant std::string_view à la place :

#include <string>
#include <string_view>

bool prefix(const std::string& a, const std::string& b) {
  if (a.size() > b.size()) {
    return std::string_view(a.c_str(),b.size()) == b;
  }
  else {
    return std::string_view(b.c_str(),a.size()) == a;
  }
}

Avec g++ 7 à -O3, cela se résume à un simple memcmp ce qui constitue une amélioration assez substantielle par rapport à l'ancienne version.

2voto

Le moyen le plus simple est d'utiliser substr() et comparer() les fonctions des membres :

string str = "Foobar";
string prefix = "Foo";

if(str.substr(0, prefix.size()).compare(prefix) == 0) cout<<"Found!";

2voto

xninja Points 201

Vous pouvez utiliser ceci :

pour c++14 ou moins

bool has_prefix
    (const std::string& str, const std::string& prefix)  {
    return str.find(prefix, 0) == 0;
}

pour c++17

//it's a little faster
auto has_prefix
    (const std::string& str, const std::string_view& prefix) -> decltype(str.find(prefix) == 0) {
    return str.find(prefix, 0) == 0;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X