【C++】string::npos
一、關於npos的定義
在MSDN中有如下說明:
basic_string::npos
static const size_type npos = -1;//定義
The constant is the largest representable value of type size_type. It is assuredly larger than max_size(); hence it serves as either a very large value or as a special code.
以上的意思是npos是一個常數,表示size_t的最大值(Maximum value for size_t)。許多容器都提供這個東西,用來表示不存在的位置,型別一般是std::container_type::size_type。
#include <iostream> #include <limits> #include <string> using namespace std; int main() { size_t npos = -1; cout << "npos: " << npos << endl; cout << "size_t max: " << numeric_limits<size_t>::max() << endl; }
執行結果為:
npos: 4294967295
size_t max: 4294967295
可見他們是相等的,也就是說npos表示size_t的最大值
二、npos的用法
1、npos可以表示string的結束位置,是string::type_size 型別的,也就是find()返回的型別。find函式在找不到指定值得情況下會返回string::npos。舉例如下(計算字串中含有的不同字元的個數):
#include <iostream>
#include <string>
using namespace std;
int main()
{
string b;
getline(cin,b);
int count=0;
for(int i=0;i<=127;i++)
if(b.find(i)!=string::npos)
count++;
cout<<count;
}
輸入123,則結果為3,如下圖所示:
舉例2:
string name("Annaqijiashe");
int pos=name.find("Anna");
if(pos==string::npos)
cout<<"Anna not found!\n";
else cout<<"Anna found at pos:"<<pos<<endl;
2、string::npos作為string的成員函式的一個長度引數時,表示“直到字串結束(until the end of the string)”。例如:
tmpname.replace(idx+1, string::npos, suffix);
這裡的string::npos就是一個長度引數,表示直到字串的結束,配合idx+1表示,string的剩餘部分。
#include <iostream>
#include <limits>
#include <string>
using namespace std;
int main()
{
string filename = "test.cpp";
cout << "filename : " << filename << endl;
size_t idx = filename.find('.'); //as a return value
if(idx == string::npos)
{
cout << "filename does not contain any period!" << endl;
}
else
{
string tmpname = filename;
tmpname.replace(idx + 1, string::npos, "xxx"); //string::npos作為長度引數,表示直到字串結束
cout << "repalce: " << tmpname << endl;
}
}
執行結果如下:
filename:test.cpp
replace: test.xxx
三、值得注意的地方:
1、npos的型別
int idx = str.find("abc");
if (idx == string::npos)
...
上述程式碼中,idx的型別被定義為int,這是錯誤的,即使定義為 unsigned int 也是錯的,它必須定義為 string::size_type。因為 string::size_type (由字串配置器 allocator 定義) 描述的是 size,故需為無符號整數型別。因為預設配置器以型別 size_t 作為 size_type,於是 -1 被轉換為無符號整數型別,npos 也就成了該型別的最大無符號值。不過實際數值還是取決於型別 size_type 的實際定義。不幸的是這些最大值都不相同。事實上,(unsigned long)-1 和 (unsigned short)-1 不同(前提是兩者型別大小不同)。因此,比較式 idx == string::npos 中,如果 idx 的值為-1,由於 idx 和字串string::npos 型別不同,比較結果可能得到 false。
要想判斷 find() 的結果是否為npos,最好的辦法是直接比較:
if (str.find("abc") == string::npos) { ... }
2、string 類提供了 6 種查詢函式,每種函式以不同形式的 find 命名。這些操作全都返回 string::size_type 型別的值,以下標形式標記查詢匹配所發生的位置;或者返回一個名為 string::npos 的特殊值,說明查詢沒有匹配。string 類將 npos 定義為保證大於任何有效下標的值。