std :: string karşılaştırması (dizenin başka bir dizeyle başlayıp başlamadığını kontrol edin)


90

Bir std: dizesinin "xyz" ile başlayıp başlamadığını kontrol etmem gerekiyor. Tüm dizede arama yapmadan veya substr () ile geçici dizeler oluşturmadan bunu nasıl yaparım.

Yanıtlar:


164

Karşılaştırma yöntemini kullanırdım:

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

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

3
Neden s.compare (t) 'yi kullanmıyorsunuz?
Franck Mesirard

5
@FranckMesirard: Bunun nedeni, varsayılan olarak karşılaştırmanın , aktarılan dizenin tüm uzunluğunu üye verileriyle karşılaştırmaya çalışması ve yanlış döndürmesi, ancak iletilen parametrenin uzunluğu doğru döndürmesini sağlarken uzunluğu vermesidir ( std :: temel_dizesi :: karşılaştırma , ofset ve uzunluk ile kullanıldığında, diğer kitaplıklarda olduğu gibi String.BeginsWith () kullanılabilir.) Uzaklık ve uzunluk olmadan bu doğru olmaz.
legends2k

1
T boşsa bu true döndürür.
gliderkite

14
@gliderkite Gerektiği gibi ... boş dizge her dizgenin ilk önekidir.
Jim Balter

1
Doğru olması gerektiği gibi ... Boş dizeleri dışlamak istiyorsanız: if (! T.empty () &&! S.compare (0, t.length (), t))
ericcurtin

14

Standart Kitaplığın ruhuna daha uygun olabilecek bir yaklaşım, algoritma ile kendi başlangıçınızı tanımlamak olacaktır.

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

Bu, istemci koduna daha basit bir arayüz sağlar ve çoğu Standart Kitaplık kapsayıcısı ile uyumludur.


Güzel! Bu, artırmak için eklenmelidir!
David

2
@David: Yükseltme izin verilen bir bağımlılıksa, bkz boost :: algoritma :: starts_with - ' Şununla başlar ' yüklem
Gabor

10

Boost için Bakma Dize Algo projenizde boost kütüphanelerin sadece bir kısmını kullanmak istiyorsanız vb starts_with, istart_with (Hassas) olarak yararlı fonksiyonlar, bir dizi hizmet veren kütüphanenin, o zaman kopya programı BCP kullanabilirsiniz sadece gerekli dosyalar


4

Görünüşe göre std :: string :: starts_with, C ++ 20'nin içinde, bu arada std :: string :: find kullanılabilir

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

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

1
Bu, kullanılan cevaptan çok daha iyidir, std::string::compareçünkü dizgenin, boyutunu bulmak için değişmezi tekrar etmeden bir değişmez ile başlayıp başlamadığını kontrol etmeyi kolaylaştırır. Ve C ++ 20 doğrudan çözümüne işaret ettiğiniz için teşekkür ederiz.
Ruslan

Eğer s1, s2 ile başlamazsa, bu yine de onu eşleştirmeye çalışacaktır ki bu, Compare () kadar iyi değildir.
A117

0

Sorunuzu tam olarak anlamadığımı hissediyorum. Önemsiz olması gerekiyor gibi görünüyor:

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

Bu yalnızca (en fazla) ilk üç karaktere bakar. Derleme zamanında bilinmeyen bir dizge için genelleme, yukarıdakileri bir döngü ile değiştirmenizi gerektirir:

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

C işlevlerini kullanırken dizeleri nasıl karşılaştıracağımı biliyorum. Sorum, C ++ STL aracılığıyla nesne yönelimli yapmakla ilgiliydi.
jackhab

Burada kullanılan C işlevi yoktur. Ve Standart Kitaplık, kendi işlemlerinizi yazmanızı engellemez.

6
ve ya t s'den daha kısaysa?
vidstige

@jackhab STL'nin yazarı "STL nesne yönelimli değildir. Bence nesne yönelimli olma neredeyse Yapay Zeka kadar bir aldatmacadır." - stlport.org/resources/StepanovUSA.html
Jim Balter

1
@vidstige Sonra döngü, sonlandırıcı NUL ile karşılaştığında sona erer t.
Jim Balter
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.