This is the most common method in the most commonly used container, but it has encountered problems recently. Let's take a look at the situation below:
#include "stdafx.h"#include <string>using namespace std;int _tmain(int argc, _TCHAR* argv[]){ string s = "UIPower"; string s2 = "owe"; size_t x = s.find("owe",1); size_t y = s.find(s2,2); return 0;}
Guess what x and y are, and many people think it's. Are there any shots! I thought so at the beginning, but after testing, I found it wrong. x and y are actually three. What is the situation?
Follow up to see how find was written and find the following code:
size_type __CLR_OR_THIS_CALL find(const _Elem *_Ptr, size_type _Off, size_type _Count) const { // look for [_Ptr, _Ptr + _Count) beginnng at or after _Off#if _HAS_ITERATOR_DEBUGGING if (_Count != 0) _DEBUG_POINTER(_Ptr);#endif /* _HAS_ITERATOR_DEBUGGING */ if (_Count == 0 && _Off <= _Mysize) return (_Off); // null string always matches (if inside string) size_type _Nm; if (_Off < _Mysize && _Count <= (_Nm = _Mysize - _Off)) { // room for match, look for it const _Elem *_Uptr, *_Vptr; for (_Nm -= _Count - 1, _Vptr = _Myptr() + _Off; (_Uptr = _Traits::find(_Vptr, _Nm, *_Ptr)) != 0; _Nm -= _Uptr - _Vptr + 1, _Vptr = _Uptr + 1) if (_Traits::compare(_Uptr, _Ptr, _Count) == 0) return (_Uptr - _Myptr()); // found a match } return (npos); // no match }
This is the code in the xstring file. It should be very underlying. Here _ Ptr is the string to be searched. Here it is "owe", and _ Off is the offset, that is, from which character to start searching, here is 1, _ Count is the length of the string to be searched, here is 3, the program goes to 12 lines, here _ Mysize is the length of the entire string, and here it is 7. here we need to make a judgment on _ Count, that is, its length cannot exceed the length of the entire string minus the offset, if it exceeds the limit, it cannot be found. The following 15 rows of loop _ Vptr are the characters after the offset. Here the corresponding character is "IPower", and _ Nm is the control program loop several times, here the disposal is set to 4, that is, there are only four possibilities, "IPo", "Pow", "owe", "wer", here _ Uptr = _ Traits :: find (_ Vptr, _ Nm, * _ Ptr ))! = 0 this function is like this:
static const _Elem *__CLRCALL_OR_CDECL find(_In_count_(_Count) const _Elem *_First, size_t _Count, const _Elem& _Ch) { // look for _Ch in [_First, _First + _Count)// _DEBUG_POINTER(_First); return ((const _Elem *)::memchr(_First, _Ch, _Count)); }
This function is used to find the position where the First character "_ Ch" appears in _ First, and return a total of _ Count characters including _ Ch, therefore, the _ Uptr returned here is the string "ower", which determines whether it is null. If it is null, the string starting with _ Ch is not found, directly jump out of the for loop. If yes, compare the string with _ Ptr. function _ Traits: compare (_ Uptr, _ Ptr, _ Count) compare the first three characters of _ Ptr and _ Uptr. Here _ Count is the length of the string to be queried. If the match succeeds, the subscript _ Ptr first appeared in _ Uptr is returned, if it is set to 0, it indicates that the matching is correct. The following describes the key return values and does not really understand the description of the _ Myptr () function, but it does not seem to play the role of adding an offset, because the returned result returns x 3, that is, the subscript of the first occurrence of the character "o", I am wondering whether the offset at the beginning of _ Off should be added to the returned result!
_Elem *__CLR_OR_THIS_CALL _Myptr() { // determine current pointer to buffer for mutable string return (_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf); }
The translation means to determine the pointer to the current variable string buffer, _ BUF_SIZE is 16, _ Myres is 15, and the returned result is naturally _ Bx. _ Buf is the string pointer, and _ Bx. the _ Buf string is the finalreturn
(_ Uptr-_ Myptr (); the difference between the two pointers returns the relative location difference between the two pointers. Naturally, we will get the answer 3. analyze the cause. I think, the system may think that _ Myptr () will return the _ Vptr pointer, but the actually returned is the _ Ptr pointer. Here the buffer operation is involved, not very clear about the specific situation, however, according to the actual results, the system returns the _ Ptr address, so it is not surprising why it is the result of 3!
This article from the "selling cute programmers" blog, please be sure to keep this source http://7677869.blog.51cto.com/7667869/1276225