C++中string::npos的一些用法总结

2023-05-16

一、关于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;
}
举例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)”。例如:
  1. 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 定义为保证大于任何有效下标的值。


参考资料:

string::npos 无符号数的陷阱 

string::npos的一些说明

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++中string::npos的一些用法总结 的相关文章

  • Java 中修剪字符串的可能前缀

    I have String str 我想从中提取不包括可能的前缀的子字符串 abc 我想到的第一个解决方案是 if str startsWith abc return str substring abc length return str
  • Delphi 2010:如何将 UTF8 编码的 PAnsiChar 转换为 UnicodeString?

    情况 我有一个外部 DLL 它使用 UTF 8 作为其内部字符串格式 接口函数都使用 PAnsiChar 来传递字符串 我的应用程序的其余部分使用 Delphi 的本机string类型 由于我正在使用 Delphi 2010 这将映射到Un
  • 将十六进制字节数组解码为特定代码页在随后编码时会产生错误结果

    我创建了一个简单的应用程序 如下所示 String stringValue new String new byte 0x00 0x00 0x00 0x25 273 byte valueEncoded Arrays copyOfRange s
  • 使用文本文件中的 var

    我的问题是 我想使用由从文本文件中在 carac 中接收的关键字启动的函数 并在该函数中使用 carac 之后的字符串 该函数位于包含的其他文件中 但我不知道该怎么做 for std string carac fichier gt gt c
  • Perl 字符串替换:匹配但不替换正则表达式的一部分

    假设我在 Perl 中有一个字符串 我正在尝试匹配并替换为以下内容 string s a zA Z find a zA Z replace g 如图所示 我想替换两侧被非字母字符包围的所有内容 但是 当我替换字符串时 我不想也替换这些字符
  • Windows 上的本机窄字符串编码是什么?

    Subversion API 有一个功能数量 http subversion apache org docs api latest svn utf 8h html用于从 本机编码 字符串转换为以 UTF 8 编码的字符串 我的问题是 Win
  • 从 C++ 中的 std::string 获取字节

    我正在一个 C 非托管项目中工作 我需要知道如何获取像 一些要加密的数据 这样的字符串并获取一个 byte 数组 我将用它作为加密的源 在 C 中我做 for int i 0 i lt text Length i buffer i byte
  • 如何用另一个子字符串替换子字符串(按索引 from..to)

    如何用其他字符串将某个字符中的子字符串替换为另一个字符 first 4 last 11 replacement show me the money replace part first last replacement gt show mo
  • C# 资源文件中的 Tab 键切换

    如何向字符串资源添加制表符 t text 不起作用 您必须显式添加制表符 最简单的方法可能是在记事本中键入字符串 显式设置制表符而不是使用转义字符 并将文本复制并粘贴到资源编辑器中 对于换行符 您也会遇到类似的问题 添加换行符的最简单方法是
  • 添加到 std::vector 的中间

    有没有办法将值添加到 a 的中间vector在 C 中 假设我有 vector
  • python执行列表和函数列表[重复]

    这个问题在这里已经有答案了 我正在将 Python 2 7 与 Autodesk Maya 结合使用 这是我的问题的一个例子 import maya cmds as m def a passedString print this passe
  • 尽管手册页有免责声明,为什么“strchr”似乎可以使用多字节字符?

    From man strchr char strchr const char s int c strchr 函数返回一个指向字符 c 在字符串 s 中第一次出现的位置的指针 这里 字符 的意思是 字节 这些函数不适用于宽字符或多字节字符 不
  • 使用 string.whitespace 删除 Python 中的空格

    Python 的 string whitespace 很棒 gt gt gt string whitespace t n x0b x0c r 如何在不手动输入 t n 等正则表达式的情况下将其与字符串一起使用 例如 它应该能够转动 请不要伤
  • 如何将整个流读入 std::string ?

    我正在尝试将整个流 多行 读入字符串中 我正在使用这段代码 它有效 但它冒犯了我的风格感 当然有更简单的方法吗 也许使用字符串流 void Obj loadFromStream std istream stream std string s
  • 使用 Hibernate 映射 Map

    似乎在我看来 到处都有过时的版本 不再起作用 我的问题看起来很简单 我有一个 Java 类 它映射到 derby 数据库 我正在使用注释 并成功地在数据库中创建了所有其他表 但在这个特定的示例中 我只需要一个 Map 它不使用任何其他类 只
  • 除括号中的空格外,将字符串拆分为所有空格

    我正在尝试将文本拆分为以下内容 例如在空格上 var line Text what is what s a story fable called named about Search Title 但我希望它忽略括号内的空格 这应该产生一个数
  • C# 中将一个字符串拆分为另一个字符串

    我一直在使用Split 分割字符串的方法 但这似乎仅在您按字符分割字符串时才有效 有没有办法分割一个string 另一个字符串是按参数分割的 我尝试将拆分器转换为字符数组 但没有成功 换句话说 我想分割string THExxQUICKxx
  • 2.5 是否有一个 Python 模块提供类似于 2.6 中的 "string".format() 调用的功能?

    2 5 是否有免费的 Python 模块提供类似于 2 6 3 x 中的 string format 调用的功能 我正在为 2 5 编写新代码 我不想在新代码中使用 格式表达式 您可能会发现这里的代码可以适应您的需要 http svn py
  • 基本 C++ 文本对齐

    我正在尝试编写一个程序 该程序从文件中获取输入行并使其恰好为 80 个字符 假设输入行始终小于 80 然后打印该行 这是通过在以下标点符号后添加最多两个空格来完成的 如果一行少于 41 个字符 则不加修改地打印 如果该行仍然不是 80 个字
  • django如何将字符串转换为模块?

    我试图了解 django 的另一个神奇之处 它可以将字符串转换为模块 In settings py INSTALLED APPS声明如下 INSTALLED APPS django contrib auth django contrib c

随机推荐