std :: so sánh chuỗi (kiểm tra xem chuỗi có bắt đầu bằng chuỗi khác hay không)


90

Tôi cần kiểm tra xem chuỗi std: có bắt đầu bằng "xyz" hay không. Làm cách nào để làm điều đó mà không cần tìm kiếm toàn bộ chuỗi hoặc tạo chuỗi tạm thời với substr ().

Câu trả lời:


164

Tôi sẽ sử dụng phương pháp so sánh:

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

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

3
Tại sao bạn không đơn giản sử dụng s.compare (t)?
Franck Mesirard

5
@FranckMesirard: Đó là bởi vì theo mặc định, so sánh sẽ cố gắng so sánh toàn bộ độ dài của chuỗi được truyền với dữ liệu thành viên và sẽ trả về false, trong khi việc cung cấp độ dài bằng độ dài của tham số được truyền sẽ khiến nó trả về true (nghĩa là std :: basic_string :: so sánh , khi được sử dụng với offset & length, có thể được sử dụng giống như String.BeginsWith () trong các thư viện khác.) Nếu không có offset và length, điều này sẽ không đúng.
Legends2k

1
Điều này trả về true nếu t rỗng.
gliderkite

14
@gliderkite Vì lẽ ra ... chuỗi rỗng là tiền tố ban đầu của mọi chuỗi.
Jim Balter

1
Như nó phải là chính xác ... Nếu bạn muốn loại trừ chuỗi rỗng: if (t.empty () && s.compare (0, t.length (), t)!)
ericcurtin

14

Một cách tiếp cận có thể phù hợp hơn với tinh thần của Thư viện Chuẩn là xác định thuật toán begin_with của riêng bạn.

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

Điều này cung cấp một giao diện đơn giản hơn cho mã máy khách và tương thích với hầu hết các vùng chứa Thư viện Chuẩn.


Mát mẻ! Điều này nên được thêm vào để thúc đẩy!
David

2
@David: Nếu boost là phần phụ thuộc được phép, hãy xem boost :: math :: start_with - vị từ 'Bắt ​​đầu với'
Gabor

10

Hãy xem thư viện String Algo của Boost , có một số chức năng hữu ích, chẳng hạn như start_with, istart_with (phân biệt chữ hoa chữ thường), v.v. Nếu bạn chỉ muốn sử dụng một phần của thư viện boost trong dự án của mình, thì bạn có thể sử dụng tiện ích bcp để sao chép chỉ những tệp cần thiết


4

Có vẻ như std :: string :: start_with nằm bên trong C ++ 20, trong khi std :: string :: find có thể được sử dụng

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

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

1
Điều này tốt hơn nhiều so với câu trả lời được chấp nhận bằng cách sử dụng std::string::comparevì nó giúp dễ dàng kiểm tra xem chuỗi có bắt đầu bằng một ký tự hay không mà không cần lặp lại chính ký tự đó để tìm kích thước của nó. Và cảm ơn bạn đã chỉ đến giải pháp trực tiếp C ++ 20.
Ruslan

Nếu s1 không bắt đầu bằng s2, điều này sẽ vẫn cố gắng so khớp nó sau đó, điều này không tốt bằng so sánh ().
A117

0

Tôi cảm thấy tôi không hoàn toàn hiểu câu hỏi của bạn. Có vẻ như nó phải là tầm thường:

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

Điều này chỉ xem xét (nhiều nhất) ba ký tự đầu tiên. Tổng quát hóa cho một chuỗi không xác định tại thời điểm biên dịch sẽ yêu cầu bạn thay thế ở trên bằng một vòng lặp:

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

Tôi biết cách so sánh các chuỗi trong việc sử dụng các hàm C. Câu hỏi của tôi là về cách thực hiện nó theo cách hướng đối tượng bằng C ++ STL.
jackhab

Không có hàm C nào được sử dụng ở đây. Và Thư viện Chuẩn không ngăn cản bạn viết các chú thích của riêng bạn.

6
và nếu t ngắn hơn s thì sao?
vidstige

@jackhab Tác giả của STL nói "STL không phải là hướng đối tượng. Tôi nghĩ rằng hướng đối tượng gần giống như một trò lừa bịp giống như Trí tuệ nhân tạo." - stlport.org/resources/StepanovUSA.html
Jim Balter

1
@vidstige Sau đó, vòng lặp kết thúc khi nó gặp NUL kết thúc trong t.
Jim Balter
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.