std :: perbandingan string (periksa apakah string dimulai dengan string lain)

90

Saya perlu memeriksa apakah std: string dimulai dengan "xyz". Bagaimana cara melakukannya tanpa mencari seluruh string atau membuat string sementara dengan substr ().

jackhab
sumber

Jawaban:

164

Saya akan menggunakan metode perbandingan:

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

if (s.compare(0, t.length(), t) == 0)
{
// ok
}
Wacek
sumber
3
Mengapa Anda tidak menggunakan s.compare (t) saja?
Franck Mesirard
5
@FranckMesirard: Itu karena secara default, pembanding akan mencoba membandingkan seluruh panjang string yang diteruskan dengan data anggota dan akan mengembalikan false, sementara memberikan panjang karena panjang parameter yang diteruskan akan membuatnya kembali benar (artinya std :: basic_string :: bandingkan , bila digunakan dengan offset & panjang, dapat digunakan seperti String.BeginsWith () di pustaka lain.) Tanpa offset dan panjang, ini tidak akan benar.
legends2k
1
Ini mengembalikan nilai true jika t kosong.
gliderkite
14
@gliderkite Seharusnya ... string kosong adalah awalan awal dari setiap string.
Jim Balter
1
Seperti yang seharusnya benar ... Jika Anda ingin menyingkirkan string kosong: if (! T.empty () &&! S.compare (0, t.length (), t))
ericcurtin
14

Pendekatan yang mungkin lebih sesuai dengan semangat Perpustakaan Standar adalah dengan menentukan algoritme begin_with Anda sendiri.

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

Ini menyediakan antarmuka yang lebih sederhana ke kode klien dan kompatibel dengan sebagian besar wadah Perpustakaan Standar.

Neutrino
sumber
Keren! Ini harus ditambahkan untuk meningkatkan!
David
2
@David: Jika peningkatan adalah ketergantungan yang diizinkan, lihat peningkatan :: algoritma :: start_with - 'Dimulai dengan' predikat
Gabor
10

Lihat pustaka String Algo Boost , yang memiliki sejumlah fungsi yang berguna, seperti begin_with, istart_with (case insensitive), dll. Jika Anda hanya ingin menggunakan sebagian pustaka boost dalam proyek Anda, Anda dapat menggunakan utilitas bcp untuk menyalin hanya file yang dibutuhkan

Alex Ott
sumber
4

Tampaknya std :: string :: begin_with ada di dalam C ++ 20, sedangkan std :: string :: find dapat digunakan

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

if (s1.find(s2) == 0)
{
   // ok, s1 starts with s2
}
Alejadro Xalabarder
sumber
1
Ini jauh lebih baik daripada jawaban yang diterima menggunakan std::string::comparekarena memudahkan untuk memeriksa apakah string diawali dengan literal tanpa mengulang literal itu sendiri untuk menemukan ukurannya. Dan terima kasih telah menunjuk ke solusi langsung C ++ 20.
Ruslan
Jika s1 tidak dimulai dengan s2, ini akan tetap mencoba mencocokkannya setelahnya, yang tidak sebagus bandingkan ().
A117
0

Saya merasa saya tidak sepenuhnya memahami pertanyaan Anda. Sepertinya itu sepele:

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

Ini hanya melihat (paling banyak) tiga karakter pertama. Generalisasi untuk string yang tidak diketahui pada waktu kompilasi akan mengharuskan Anda mengganti yang di atas dengan loop:

// look for t at the start of s
for (int i=0; i<s.length(); i++)
{
  if (s[i]!=t[i])
    return false;
}
1800 INFORMASI
sumber
Nah, saya tahu bagaimana membandingkan string dalam menggunakan fungsi C. Pertanyaan saya adalah tentang melakukannya dengan cara berorientasi objek melalui C ++ STL.
jackhab
Tidak ada fungsi C yang digunakan di sini. Dan Perpustakaan Standar tidak menghalangi Anda untuk menulis unctions Anda sendiri.
6
dan bagaimana jika t lebih pendek dari s?
vidstige
@jackhab Penulis STL mengatakan "STL tidak berorientasi objek. Saya pikir orientasi objek hampir sebanyak tipuan seperti Artificial Intelligence." - stlport.org/resources/StepanovUSA.html
Jim Balter
1
@vidstige Kemudian loop berakhir ketika menemukan NUL yang mengakhiri di t.
Jim Balter