2014-02-09 63 views
5

我正在通過一本關於C++的書,它只是使用string::npos來檢查字符位置是否存在於字符串中。不過,我不明白這個機制怎麼可能知道我指的是哪個字符串!這個特定的代碼正在計算一個子串的出現次數。string :: npos如何知道我指的是哪個字符串?

代碼:

for (int i=cats.find("cat",0);i!=string::npos;i=cats.find("cat",i)) { 
    ++catCount; 
    ++i; 
} 

我明白它正在啓動在字的第一次出現的環路,遞增計數器每經過,以避免兩次計數相同的子串,然後在端每個循環的計數器跳到子串的下一個出現位置。當計數器不存在作爲字符串的字符索引時,循環停止。

該字符串被稱爲貓雖然和「貓」沒有在「string :: npos」中找到,所以如何知道這是我甚至搜索的變量?這是否僅僅是因爲這是最後變量.find()

謝謝!

+1

這只是一個常數,如果find不能找到它,它就會返回。 – chris

+1

find()返回保存爲std :: string的靜態數據成員的值npos,如果找不到字符串。 – 0x499602D2

+1

我假設「靜態數據成員」與其他OO語言中的意思相同,即如果從程序中的任何位置訪問相同的值,並且該對象的任何實例都不需要目前的價值被訪問和操縱? –

回答

8

如果find無法找到您要查找的內容,則會返回一個定位值std::string::npos。沒有必要知道關於字符串本身的任何信息。所有需要的是返回一個不能成爲有效索引的值。

例如,它可以被實現爲:

static const size_t npos = std::numeric_limits<size_t>::max(); 

size_t string::find(...) 
{ 
    // if we didn't find it... 
    return npos; 
} 

而且,你不應該使用int存儲的返回值,因爲它是不是有什麼find回報。如果你有很長的字符串,返回的索引>numeric_limits<int>.max()?那麼現在你已經調用了未定義的行爲。

+0

因此,然後我必須在調用find()之前檢查string :: npos,因爲這是一個靜態屬性,對嗎? –

+1

@JS爲了確定find()是否返回了一個有效的索引,你應該檢查返回值,看它是否不返回值'std :: string :: pos'。由於'npos'的「靜態」性質,沒有必須採取強制性措施。 find()只是在它找不到字符串時返回一個特殊值,並且要知道它是否返回了一個有效的索引,則需要檢查返回值是否不是特殊值。 – 0x499602D2

+1

@JS:不可以,因爲@ 0x499602D2表示它只是一個哨兵值,即從'fi​​nd'返回的值可以用來確定是否找到了您要查找的字符串。它是靜止的事實是無關緊要的。如果'find'找不到你要找的東西,它會返回'npos',所以現在你知道它沒有。如果它返回了'npos'以外的內容,那麼你知道它是一個有效的索引到你的字符串中。 –

5

find返回一個std::string::size_typestd::string::npos是當找不到該值時返回的那種類型的常量。

注意std::string::size_typeunsigned值,int簽署。如果std::string::npos不能表示爲int,那麼從std::string::nposint的轉換是未定義的行爲。

所以你真的不應該在int中存儲std::string::find的返回值。相反,您應該將其存儲在std::string::size_type中,或者在C++ 11中使用autobaisc_string<char>size_typestd::size_t,正如大多數其他專業。

+0

@ douglaso.moen'basic_string'有一個未指定的'size_type':你說'std :: basic_string ''有一個'size_type'由標準指定? – Yakk

+0

@ Douglaso.moen我有很多理由不同意你的觀點。首先,[live code](http://ideone.com/ON7MWS)。二,目前草案標準21.4/5類模板 basic_string [基本。字符串]明確提到'size_type',而'std :: string' **是**'std :: basic_string '。有'std :: string :: size_type'這樣的東西,它恰好是'std :: size_t'。如果我錯了,你能否提供一個引用? – Yakk

3

它不知道你指的是什麼樣的字符串,npos只是表示表示的最大值,在這種情況下,代表和eror,如果我們看一下cppreference靜態const成員說,關於std::basic_string::npos

static const size_type npos = -1; 

這是一個特殊值,它等於size_type類型可表示的最大值。確切的含義取決於上下文,但它通常用作字符串末尾指示符,由期望字符串索引的函數或由返回字符串索引的函數作爲錯誤指示符。

這部分21.4類模板的basic_string段落匹配的定義爲nposdraft C++ standard

static const size_type npos = -1; 

這是有點奇數自從SIZE_TYPE無符號但是由於第4.7積分轉換規則它說:

如果目標類型是無符號的,所得到的值是至少無符號整數全等到源整數(模2n,其中n是用於表示無符號類型的比特的數量)[。 ..]

保證-1將被轉換爲最大的無符號值。它可以更容易地看到使用從草案C99標準,它說,措詞:

否則,如果新類型是無符號的,所述值是通過反覆增加或 減去超過最大值多一個轉換,可以在新類型 中表示,直到該值處於新類型的範圍內。

它給我們MAX + 1 -1這是MAX

相關問題