我正在编写一本关于C ++的书,它只是使用string::npos
来检查字符串中是否存在字符位置。我不明白这个机制怎么可能知道我指的是哪个字符串呢!此特定代码计算子字符串的出现次数。
代码:
for (int i=cats.find("cat",0);i!=string::npos;i=cats.find("cat",i)) {
++catCount;
++i;
}
据我所知,它是在第一次出现的时候开始循环,每次通过都会递增计数器以避免计算两次相同的子串,然后在每次循环结束时计数器跳转到该位置。下一次出现的子串。当计数器不存在作为字符串的字符索引时,循环停止。
这个字符串虽然被称为“猫”,而“string :: npos”中找不到“猫”,所以它知道这是我甚至在搜索的变量吗?这只是因为那是调用.find()
的最后一个变量吗?
谢谢!
答案 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_type
。 std::string::npos
是该类型的常量,当找不到该值时返回该常量。
请注意,std::string::size_type
是 unsigned
值,int
已签名。如果std::string::npos
无法表示为int
,则从std::string::npos
到int
的转换是未定义的行为。
所以你真的不应该将std::string::find
的返回值存储在int
中。相反,您应该将其存储在std::string::size_type
或C ++ 11中使用auto
。与大多数其他专业化一样,baisc_string<char>
size_type
为std::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
。