程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> STL中string容器的find方法

STL中string容器的find方法

編輯:關於C語言

這是一個最常用的容器中的最常用的方法,可是最近在用的時候卻出現了問題。下面大家看看這是什麼情況吧:

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

猜猜x,y分別是多少吧,有不少人認為是2,1吧,有沒有中槍!反正我開始時這麼認為的,但是經過測試發現不對啊,x,y居然都是3,什麼情況?

跟蹤進去看看find到底是怎麼寫的,發現下面這段代碼

   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
       }

這是xstring文件中的代碼,應該是很底層的東西了這裡的_Ptr是要查找的字符串,這裡就是"owe"了,_Off是偏移量,也就是從哪個字符開始查找的,這裡就是1了,_Count就是要查找的字符串的長度,這裡就是3了,程序走到12行,這裡的_Mysize就是整個字符串的長度,這裡就是7了,這裡要對_Count進行一個判斷,也就是它的長度不能超過整個字符串的長度減去偏移量的大小,超過了就肯定找不到了,下面15行的循環_Vptr就是偏移後的字符,這裡對應的應該是"IPower",_Nm是控制程序循環幾次,這裡處置設置為4,也就是只能有4種可能,"IPo","Pow","owe","wer",這裡這個_Uptr = _Traits::find(_Vptr, _Nm, *_Ptr)) != 0這個函數跟進去看看是這樣的:

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

這個函數的意思是在_First中找第一個字符_Ch出現的位置,並把包括_Ch在內的總共_Count個字符返回,所以這裡返回得到的_Uptr是字符串"ower",對這個_Uptr判斷其是否為空,如果為空說明沒有找到以字符_Ch開始的字符串,直接跳出for循環,如果找到了就對這個字符串和_Ptr做比較,函數_Traits::compare(_Uptr, _Ptr, _Count)比較_Ptr和_Uptr的前3個字符,這裡_Count是要查詢的字符串的長度,匹配成功返回_Ptr在_Uptr中首次出現的下標,如果為0就說明正確匹配了,下面看關鍵的返回值,真心不明白這個_Myptr()函數干了說明,但是貌似沒有起到加偏移量的作用,因為最後返回得到的x是3,也就是字符"o"首次出現的下標,所以我在想,這個最後返回的結果是不是應該加上_Off這個開始時候的偏移量!

_Elem *__CLR_OR_THIS_CALL _Myptr()
        {   // determine current pointer to buffer for mutable string
        return (_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf);
        }

翻譯過來的意思是確定當前的可變的字符串緩沖區的指針,_BUF_SIZE是16,_Myres是15,返回的自然是_Bx._Buf這個字符串指針了,而_Bx._Buf這個字符串就是,最後的return(_Uptr - _Myptr()); 兩個指針做差返回的是兩個指針的相對位置差,自然會得到3這樣的答案,分析原因,我覺得,可能系統以為_Myptr()返回的會是_Vptr這個指針,但是實際返回的是_Ptr這個指針,這裡涉及到緩沖區的操作,不是很清楚裡面的具體情況,但是根據實際結果看這裡系統確實返回的是_Ptr的地址,所以不奇怪為什麼都會是3這個結果了!

本文出自 “賣萌程序員” 博客,請務必保留此出處http://7677869.blog.51cto.com/7667869/1276225

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved