彻底搞懂C++中string::npos

彻底搞懂C++中string::npos

什么是string::npos

C++手册里面给出的定义是这样的,string::npos就是一个公有的静态的常量类型的成员变量。使用前需要包含头文件。

具体定义如下:

static const size_type	npos = static_cast<size_type>(-1);

这里的size_type就是类型size_t,size_t是一个无符号整形,那么-1也就是其最大值。

那么npos其实就是size_t的最大值,放到string类中也代表着:”until the end of the string”,作为一个返回值,在string类中代表的意思就是没有找到任何匹配字段(find, rfind, find_first_of,find_first_not_of等);

所以不要对npos有什么畏惧,它就是一个值,一个无符号整形的最大值。

什么地方用到了string::npos

std::string::npos 及时一个特殊的常量值,正式有了这个值才能让string和其他stl的迭代器使用不一样,也正是因为有了它才能让string类型的查找相对于其他同类型的stl查找效率更高。

string::npos常被用于find, rfind, find_first_of, find_last_of, find_first_not_of, substr, erase和find_last_not_of`,这些函数返回的类型都是size_t类型,当这些函数返回值和string::npos相等时说明查询到字符串结尾也没有找到查找的字符/字符子串。

string::npos的正确用法

使用stl迭代器习惯了很容易写出这样的代码,但是编译的时候却发现编译出错,这时因为find返回的时size_t类型的值,而不是迭代器。

auto iter = name.find('d');
if (iter != name.end()) {

}

正确的用法如下:

// 查找s2字符串在s1中的位置 
void fun(string s1, string s2)
{
    // 查找s2字符串在s1中的位置 
    auto found = s1.find(s2);
    // 检查位置是否等于string::npos,如果不等说明找到了,如果相等说明没找到
    if (found != string::npos) {
        cout << "first " << s2 << " found at: " << (found)
             << endl;
    } else {
        cout << s2 << " is not in"
             << "the string" << endl;
    }
}

如果你不确定find返回值类型,最好使用auto,而不要使用int等类型承接,这样如果类型大小不一样会导致判断失误,比如你用uint16_t类型接返回值,来和string::npos判断是否相同,两个值都被赋值-1是,得到的值是不同的,一个是0xffff,一个是0xffffffff。

使用string::npos来去除字符串中的元音字母

std::string Disemvowel(const std::string& str) {
    // 定义一个字符串,用来承接剔除元音字母之后的字符串
    std::string vowelless;

    // 定义一个包含所有原因字母的字符串
    std::string vowels = "aeiouAEIOU";

    // 迭代查找,如果不是元音字母,就把它放到vowelless中
    for (char c : str) {
        if (vowels.find(c) == std::string::npos) {
            vowelless +=  c;
        }
    }

    // 将所有非原因字母组成的字符串返回
    return vowelless;
}

因此,可以看出std::string::npos是一个特殊的常量值,用来说明没有查找到的状态,这个值被用于std::string的很多成员函数,当这些成员函数返回std::string::npos时就说明没有找到你期望的值。

你可能感兴趣的:(C-C++,c++,开发语言)