string::npos的一些说明

一、定义

std::string::npos的定义:

  1. static const size_t npos = -1;  

表示size_t的最大值(Maximum value for size_t,如果对 -1表示size_t的最大值有疑问可以采用如下代码验证:

  1. #include <iostream>  
  2. #include <limits>  
  3. #include <string>  
  4. using namespace std;  
  5.   
  6. int main()  
  7. {  
  8.     size_t npos = -1;  
  9.     cout << "npos: " << npos << endl;  
  10.     cout << "size_t max: " << numeric_limits<size_t>::max() << endl;  
  11. }  

在我的PC上执行结果为:

                 npos:           4294967295

                 size_t max:  4294967295

可见他们是相等的,也就是说npos表示size_t的最大值


二、使用

2.1 如果作为一个返回值(return value)表示没有找到匹配项,例如:

  1. #include <iostream>  
  2. #include <limits>  
  3. #include <string>  
  4. using namespace std;  
  5.   
  6. int main()  
  7. {  
  8.     string filename = "test";  
  9.     cout << "filename : " << filename << endl;  
  10.   
  11.     size_t idx = filename.find('.');   //作为return value,表示没有匹配项  
  12.     if(idx == string::npos)      
  13.     {  
  14.         cout << "filename does not contain any period!" << endl;  
  15.     }  
  16. }  

2.2 但是string::npos作为string的成员函数的一个长度参数时,表示“直到字符串结束(until the end of the string)”。例如:

  1. tmpname.replace(idx+1, string::npos, suffix);  

这里的string::npos就是一个长度参数,表示直到字符串的结束,配合idx+1表示,string的剩余部分。

  1. #include <iostream>  
  2. #include <limits>  
  3. #include <string>  
  4. using namespace std;  
  5.   
  6. int main()  
  7. {  
  8.     string filename = "test.cpp";  
  9.     cout << "filename : " << filename << endl;  
  10.   
  11.     size_t idx = filename.find('.');   //as a return value  
  12.     if(idx == string::npos)      
  13.     {  
  14.         cout << "filename does not contain any period!" << endl;  
  15.     }  
  16.     else  
  17.     {  
  18.         string tmpname = filename;  
  19.         tmpname.replace(idx + 1, string::npos, "xxx"); //string::npos作为长度参数,表示直到字符串结束  
  20.         cout << "repalce: " << tmpname << endl;  
  21.     }  
  22. }  

执行结果为:

filename:test.cpp

replace: test.xxx

三、值得注意的地方:
1、npos的类型
  1. int idx = str.find("abc");  
  2. if (idx == string::npos)  
  3.   ...  
上述代码中,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 定义为保证大于任何有效下标的值。


猜你喜欢

转载自blog.csdn.net/sugarbliss/article/details/80064597