string s = "UIPower";
string s2 = "owe";
size_t x = s.find("owe", 1); // 從下標 1 開始找 "owe"
size_t y = s.find(s2, 2); // 從下標 2 開始找 s2
// 預期 x=2, y=1,實際 x=3, y=3
查看 MSVC STL xstring 中 find(const _Elem* _Ptr, size_type _Off, size_type _Count) 實現:
_Off 為起始偏移,_Count 為模式串長度。_Traits::find(_Vptr, _Nm, *_Ptr) 尋找模式串首字符(此處 'o')。_Traits::compare(_Uptr, _Ptr, _Count) 比較前 _Count 字符。_Uptr - _Myptr() —— 這裡的關鍵:_Myptr() 返回的是字符串緩衝區起始地址,而非 _Vptr(偏移後地址)!_Myptr() 內部邏輯:
_Elem* _Myptr() {
return (_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf); // 總是返回緩衝區首地址
}
因此 _Uptr - _Myptr() 計算的是模式串在原字符串中的絕對下標,而非相對於 _Off 的相對下標。這導致無論 _Off 為多少,返回值始終是模式串首字符在原串中的首次出現位置。
string s = "UIPower"; // 下標: 0:U 1:I 2:P 3:o 4:w 5:e 6:r
s.find("owe", 1); // 返回 3('o' 在原串下標 3)
s.find("owe", 2); // 仍返回 3
s.find("owe", 3); // 仍返回 3
s.find("owe", 4); // 返回 npos(因為 'o' 在 3,已被跳過)
pos 的匹配位置」,MSVC 選擇返回全局首次出現位置。std::search 配合迭代器範圍。// 手動實現帶偏移的精確查找
size_t find_from(const string& haystack, const string& needle, size_t pos) {
if (pos > haystack.size()) return string::npos;
auto it = std::search(haystack.begin() + pos, haystack.end(),
needle.begin(), needle.end());
return (it != haystack.end()) ? (it - haystack.begin()) : string::npos;
}