std :: การเปรียบเทียบสตริง (ตรวจสอบว่าสตริงเริ่มต้นด้วยสตริงอื่นหรือไม่)


90

ฉันต้องการตรวจสอบว่า std: string ขึ้นต้นด้วย "xyz" หรือไม่ ฉันจะทำได้อย่างไรโดยไม่ต้องค้นหาสตริงทั้งหมดหรือสร้างสตริงชั่วคราวด้วย substr ()

คำตอบ:


164

ฉันจะใช้วิธีการเปรียบเทียบ:

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

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

3
ทำไมคุณไม่ใช้ s.compare (t) ล่ะ?
Franck Mesirard

5
@FranckMesirard: นั่นเป็นเพราะโดยค่าเริ่มต้นการเปรียบเทียบจะพยายามเปรียบเทียบความยาวทั้งหมดของสตริงที่ส่งผ่านกับข้อมูลสมาชิกและจะส่งคืนเป็นเท็จในขณะที่การให้ความยาวเป็นความยาวของพารามิเตอร์ที่ผ่านจะทำให้กลับเป็นจริง (หมายถึงstd :: basic_string :: เปรียบเทียบเมื่อใช้กับ offset & length สามารถใช้งานได้เช่น String.BeginsWith () ในไลบรารีอื่น ๆ ) หากไม่มีออฟเซ็ตและความยาวสิ่งนี้จะไม่เป็นจริง
legends2k

1
สิ่งนี้จะคืนค่าจริงถ้า t ว่างเปล่า
gliderkite

14
@gliderkite ตามที่ควรจะเป็น ... สตริงว่างคือคำนำหน้าเริ่มต้นของทุกสตริง
Jim Balter

1
ตามที่ควรจะถูก ... หากคุณต้องการตัดสตริงว่าง: if (! t.empty () &&! s.compare (0, t.length (), t))
ericcurtin

14

แนวทางที่อาจสอดคล้องกับเจตนารมณ์ของไลบรารีมาตรฐานคือการกำหนดอัลกอริทึม begin_with ของคุณเอง

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

สิ่งนี้ให้อินเทอร์เฟซที่ง่ายกว่าสำหรับโค้ดไคลเอ็นต์และเข้ากันได้กับคอนเทนเนอร์ไลบรารีมาตรฐานส่วนใหญ่


เย็น! สิ่งนี้ควรเพิ่มเพื่อบูสต์!
เดวิด

2
@David: หากการเพิ่มเป็นการพึ่งพาที่อนุญาตโปรดดู boost :: algorithm :: start_with - 'เริ่มต้นด้วย' เพรดิเคต
Gabor

10

มองไปที่ไลบรารีString Algoของ Boost ซึ่งมีฟังก์ชันที่มีประโยชน์มากมายเช่น start_with, istart_with (case insensitive) เป็นต้นหากคุณต้องการใช้เฉพาะบางส่วนของ boost libraries ในโปรเจ็กต์ของคุณคุณสามารถใช้ยูทิลิตี้ bcp เพื่อคัดลอก ไฟล์ที่จำเป็นเท่านั้น


4

ดูเหมือนว่า std :: string :: start_with อยู่ภายใน C ++ 20 ในขณะที่ std :: string :: find สามารถใช้ได้

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

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

1
สิ่งนี้ดีกว่าคำตอบที่ยอมรับโดยใช้std::string::compareเนื่องจากทำให้ง่ายต่อการตรวจสอบว่าสตริงขึ้นต้นด้วยตัวอักษรหรือไม่โดยไม่ต้องใช้ตัวอักษรซ้ำเพื่อค้นหาขนาด และขอขอบคุณที่ชี้ไปที่โซลูชันโดยตรง C ++ 20
Ruslan

หาก s1 ไม่ขึ้นต้นด้วย s2 สิ่งนี้จะยังคงพยายามจับคู่ในภายหลังซึ่งไม่ดีเท่าการเปรียบเทียบ ()
A117

0

ฉันรู้สึกว่าไม่เข้าใจคำถามของคุณอย่างเต็มที่ ดูเหมือนว่ามันควรจะเป็นเรื่องเล็กน้อย:

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

สิ่งนี้จะดูเฉพาะ (มากที่สุด) อักขระสามตัวแรก การวางนัยทั่วไปสำหรับสตริงที่ไม่เป็นที่รู้จักในเวลาคอมไพล์คุณจะต้องแทนที่ด้านบนด้วยลูป:

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

ฉันรู้วิธีเปรียบเทียบสตริงในการใช้ฟังก์ชัน C คำถามของฉันเกี่ยวกับการทำแบบเชิงวัตถุโดยใช้ C ++ STL
jackhab

ที่นี่ไม่มีการใช้ฟังก์ชัน C และ Standard Library ไม่ได้กีดกันคุณจากการเขียน unctions ของคุณเอง

6
แล้วถ้า t สั้นกว่า s ล่ะ?
vidstige

@jackhab ผู้เขียน STL กล่าวว่า "STL ไม่ใช่เชิงวัตถุฉันคิดว่าการมุ่งเน้นวัตถุเป็นเรื่องหลอกลวงพอ ๆ กับปัญญาประดิษฐ์" - stlport.org/resources/StepanovUSA.html
Jim Balter

1
@vidstige จากนั้นลูปจะสิ้นสุดลงเมื่อพบกับ NUL ที่สิ้นสุดในt.
Jim Balter
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.