string :: npos如何知道我指的是哪个字符串?

时间:2014-02-09 02:49:23

标签: c++ string

我正在编写一本关于C ++的书,它只是使用string::npos来检查字符串中是否存在字符位置。我不明白这个机制怎么可能知道我指的是哪个字符串呢!此特定代码计算子字符串的出现次数。

代码:

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

据我所知,它是在第一次出现的时候开始循环,每次通过都会递增计数器以避免计算两次相同的子串,然后在每次循环结束时计数器跳转到该位置。下一次出现的子串。当计数器不存在作为字符串的字符索引时,循环停止。

这个字符串虽然被称为“猫”,而“string :: npos”中找不到“猫”,所以它知道这是我甚至在搜索的变量吗?这只是因为那是调用.find()的最后一个变量吗?

谢谢!

3 个答案:

答案 0 :(得分:9)

如果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返回的值。如果你有一个很长的字符串并且返回的索引是&gt; numeric_limits<int>.max()?那么现在你已经调用了未定义的行为。

答案 1 :(得分:5)

find返回std::string::size_typestd::string::npos是该类型的常量,当找不到该值时返回该常量。

请注意,std::string::size_type unsigned 值,int已签名。如果std::string::npos无法表示为int,则从std::string::nposint的转换是未定义的行为。

所以你真的不应该将std::string::find的返回值存储在int中。相反,您应该将其存储在std::string::size_type或C ++ 11中使用auto。与大多数其他专业化一样,baisc_string<char> size_typestd::size_t

答案 2 :(得分:3)

它不知道你指的是什么字符串,npos只是一个静态const成员,表示可表示的最大值,在这种情况下表示和eror,如果我们看一下cppreference所说的{{3 }}:

static const size_type npos = -1;
  

这是一个特殊值,等于size_type类型可表示的最大值。确切的含义取决于上下文,但它通常用作期望字符串索引的函数作为字符串指示符的结尾,或者作为返回字符串索引的函数的错误指示符。

符合npos 类模板basic_string 5 中<{3}}中21.4的定义:

static const size_type npos = -1;

这有点奇怪,因为 size_type 无符号,但是由于4.7 部分中的积分转换规则积分转换其中说:

  

如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模2n,其中n是用于表示无符号类型的位数)。[...]

保证将-1转换为最大的无符号值。使用C99标准草案中的措词可能更容易看出:

  

否则,如果新类型是无符号的,则通过重复添加或转换该值   减去一个可以在新类型中表示的最大值   直到该值在新类型的范围内。

给我们MAX + 1 -1 MAX