2009-06-18 59 views
3

我在一個字符串中進行一系列的搜索,並且沿着這一行的某個字符串將被錯過,並且我的搜索集合應該失敗。爲什麼std :: string.find(text,std :: string:npos)不返回npos?

我曾預料,一旦位置達到std :: string :: npos它會留在那裏,但它不會。路過的std :: string ::非營利組織爲std :: string.find似乎開始在搜索開始再次

std::string str("frederick"); 
std::string::size_type pos = str.find("der",std::string::npos); 
TS_ASSERT_EQUALS(pos, std::string::npos); // FAIL, 3 is returned 

爲什麼不採取表示字符串的結束?

更新: 目的是尋求以一系列字符串,並在年底

pos = str.find(string1, pos) 
pos = str.find(string2, pos) 
pos = str.find(string3, pos) 
if (pos != std:string::npos) 
{ // All strings found 
+1

傳遞-1(npos)作爲開始查找子字符串的位置的要點是什麼? – Gishu 2009-06-18 09:49:24

+0

@Gishu我已經添加了一些示例代碼 – 2009-06-18 10:03:57

+2

用g ++試過你的代碼,並且找到並返回npos。我認爲Charles Bailey是對的。 – mweerden 2009-06-18 10:17:31

回答

10

的規格來看,我認爲有可能是您的實現中的錯誤。

basic_string::find應返回的最低位置xpos使得pos <= xposxpos + str.size() <= size()at(xpos + I) == str.at(I)所有元素I通過str控制。

basic_string::npos是-1轉換爲無符號類型,因此必須是該無符號類型可表示的最大數字。鑑於沒有其他位置xpos能滿足甚至npos < = xposfind第一部分必須在失敗時返回npos,據我所看到nposbasic_string::find當傳遞npos作爲第二個參數的唯一有效返回值。

0

檢查結果傳遞的std :: string ::非營利組織作爲第二個參數找到辦法「開始在字符串「std :: string :: npos位置上或之後查找」。

顯然這不是你想要的。

編輯:

這可能會做你原本打算:

string s; 
string::size_type pos; 

if ((pos = s.find(s1)) != string::npos && (pos = s.find(s2, pos)) != npos && 
    (pos = s.find(s3,pos)) != string::npos) 
{ 
    // okay 
} 

我沒有測試它,但它應該工作,你可能更喜歡peterchen風格,因爲它是更具可讀性。

+0

這是我的意圖,我已經更新了代碼,以顯示如何。 – 2009-06-18 10:02:43

0

您應該將字符串的長度作爲起始位置。

3

std::string::npos對於std::string::find不是有效的參數。

標準中find的定義僅提到npos作爲可能的返回值,而不是起始位置。如果你通過npos

1

行爲是不確定的:

[更新]
STL文件(這兩個複製品可以找我,反正)提到string::npos僅作爲可能的返回值,不能作爲pos有效值。後者是搜索開始的索引。

但也請參閱下面的評論(我不是ISO標準的專家,我限制了我基於文檔的預期)。

的STL實現通常採用明碼實價,超出範圍的值(如((size_type)-1)。這是如何作爲參數處理沒有明確規定,所以我不會依賴於這種行爲。 [/更新]

所以你需要在0開始,並檢查pos != npos每次調用後發現:

pos = str.find(string1, 0) 
if (pos != std:string::npos) 
    pos = str.find(string2, pos) 
if (pos != std:string::npos) 
    pos = str.find(string3, pos) 

if (pos != std:string::npos) 
{ 
    // All strings found 
} 
3

您可能會發現在這種情況下,免費函數std :: search更易於使用。例如。

std::string::const_iterator iter = str.begin(); 

iter = std::search(iter, str.end(), string1.begin(), string1.end()); 
iter = std::search(iter, str.end(), string2.begin(), string2.end()); 
iter = std::search(iter, str.end(), string3.begin(), string3.end()); 
4

比較string :: find()和string :: copy()。 (在N2798,即21.3.7.2和21.3.6.7,第686/687頁)兩者都有一個立場參數。然而,只有string :: copy有一個「Requires:pos < = size()」子句。因此,string :: find確實是而不是 require pos < = size()。

從那時起,Charles Bailey有了正確的邏輯。查看有效返回值的範圍,並且很明顯,只有與rqeirements匹配的唯一返回值是string :: npos。返回的任何其他值都小於string :: npos,失敗21.3.7.2/1。


從N2798 = 08-0308,版權ISO/IEC:

21.3.7.2 basic_string::find [string::find]

size_type find(const basic_string<charT,traits,Allocator>& str,size_type pos = 0) const;

1種效果:確定最低位置xpos,如果可能的話,使得以下兩個條件獲得: - pos <= xposxpos + str.size() <= size(); - traits::eq(at(xpos+I), str.at(I))所有元素I的字符串由str控制。 2返回:xpos如果函數可以確定這樣一個值爲xpos。否則,返回npos。 3備註:用途traits::eq()

相關問題