如何在C++中使用字符串的find()方法

在本文中,我们将看看如何在C++中使用字符串的find()函数。

如果我们想要检查一个字符串是否包含另一个字符串,std::string.find() 方法非常有用。让我们通过一些例子来理解如何使用这个方法!


C++中字符串find()的语法

这个方法属于C++的字符串类(std::string)。因此,我们必须包含头文件。

我们必须在一个字符串对象上调用这个函数,并使用另一个字符串作为参数。

然后,find()方法会检查给定的字符串是否存在于我们的字符串中。它将返回包括’\0’终止字符在内的子字符串的大小(作为size_t)。但是,如果字符串不在我们的原始字符串中,它将返回0。

有了这个,这个函数就被定义成了这样:

size_t find(const std::string& my_string, size_t pos = 0);

还有一个参数,pos,它定义了搜索的起始位置。

默认情况下,开始位置是0,所以除非你明确指定开始位置,否则搜索将从字符串的开头开始。

同样注意到字符串被以常量引用的方式传递。

由于我们不会修改任何字符串,因此不浪费时间创建临时字符串更有意义,因为我们可以直接使用引用进行操作。

注意:从C++20开始,许多标准库方法现在支持constexpr,因此它们在编译时执行。您可以在线阅读更多关于constexpr的复杂性。

有一些函数重载,其中大部分我将跳过,因为你可以在这个页面上查看更多信息。相反,我们将重点关注一个特定的重载,涉及子字符串的长度。

size_t find( const Char* s, size_type pos, size_type count )

这个特定的重载会检查子字符串是否位于我们的字符串中,但它还对子字符串的长度有限制。它会匹配直到指定的字符数。

但这不能用于 std::string。请注意原型中的 const Char*。因此,我们只能用于 C 风格的字符串。

例如,如果我们将子字符串“Hell”传递给这个函数中的“Hello”。

std::cout << "Hello".find("Hell", 0, 3) << std::endl;

这只会匹配从“Hello”开始的3个字符。所以,作为输出,我们只会得到4个字节而不是5个字节。

现在让我们来看一些例子,以便理解我们学到的知识。


在C++中使用string.find()函数

让我们来看一下默认的调用,当pos=0时。我们将简单地搜索整个子字符串,从字符串的开头开始。

#include <iostream>
#include <string>

int main() {
    // Create our string
    std::string my_str("Hello from JournalDev");
    // Target string to search for
    std::string target_string("JournalDev");

    std::cout << "Is " << target_string << " a substring of " << my_str << " ?\n";
    size_t substring_length = my_str.find(target_string);
    if (substring_length == 0)
        std::cout << "No\n";
    else
        std::cout << "Length of matched substring = " << substring_length << std::endl;

    return 0;
}

输出:只需要提供一个选项。

Is JournalDev a substring of Hello from JournalDev ?
Length of matched substring = 11

你可以看到,在我们的原始字符串中确实有这个子串!

现在让我们从字符串的特定位置开始搜索相同的子字符串。

#include <iostream>
#include <string>

int main() {
    // Create our string
    std::string my_str("Hello from JournalDev");
    // Target string to search for
    std::string target_string("JournalDev");

    std::cout << "Is " << target_string << " a substring of " << my_str << " ?\n";
    size_t substring_length = my_str.find(target_string, 12); // Start from index 12 (from my_str[12])
    if (substring_length == 0)
        std::cout << "No\n";
    else
        std::cout << "Length of matched substring = " << substring_length << std::endl;

    return 0;
}

输出

Is JournalDev a substring of Hello from JournalDev ?
Length of matched substring = 18446744073709551615

为什么我们得到了这样奇怪的输出?因为我们从原始字符串的第12个索引开始,并且我们的子字符串的长度从这个位置开始将超过原始字符串的长度!

因此,当我们到达字符串的末尾时,我们会前往一个垃圾位置。需要注意的是,find()会超出字符串的末尾。

因此,我们将通过检查是否已到达字符串的末尾来修复这个危险状态。

C++有一个特殊的变量叫做std::string::npos,它返回一个指向当前字符串的句柄,我们可以用它来检测我们是否到达了字符串的结尾。

if (my_str.find(target_str) != std::string::npos) {
    // This matches! We're still within the original string
}
else {
    // Oops! Out of bounds. Print error message!
}

随着这个变化,我们的代码现在将变成这样:

#include <iostream>
#include <string>

int main() {
    // Create our string
    std::string my_str("Hello from JournalDev");
    // Target string to search for
    std::string target_string("JournalDev");

    std::cout << "Is " << target_string << " a substring of " << my_str << " ?\n";
    size_t substring_length;
    if ((substring_length = my_str.find(target_string, 12)) != std::string::npos) {
        std::cout << "Length of matched substring = " << substring_length << std::endl;
    }
    else {
        std::cout << "No\n";
    }

    return 0;
}

输出

Is JournalDev a substring of Hello from JournalDev ?
No

现在,我们得到了我们期望的输出,因为我们从索引12开始!

让我们使用这个检查来展示find()的另一种重载形式,使用计数。请记住,我们不能直接在C++字符串上使用这种形式。

#include <iostream>
#include <string>

int main() {
    // Create our string
    std::string my_str("Hello from JournalDev");
    // Target string to search for
    std::string target_string("Journ_kkfffsfsfskkk");

    std::cout << "Is " << target_string << " a substring of " << my_str << " ?\n";
    size_t substring_length;
    // Use a count to match only 5 characters
    // Note that we can use this form only for const char* strings
    if ((substring_length = my_str.find("Journ_kkfffsfsfskkk", 0, 5)) != std::string::npos) {
        std::cout << "Length of matched substring = " << substring_length << std::endl;
    }
    else {
        std::cout << "No\n";
    }

    return 0;
}

输出

Is Journ_kkfffsfsfskkk a substring of Hello from JournalDev ?
Length of matched substring = 11

观察到我们已经改变了我们的目标字符串。在这里,尽管只有前5个字符会被匹配,但对于find()来说已经足够了,因为我们设置了一个计数限制为5!

所以,它将简单地忽略目标子字符串的其余部分,并继续匹配我们原始字符串直到字符串的末尾!

这就是为什么我们仍然得到11,因为它是找到子字符串匹配的地方。


结论

希望通过这些例子,您已经明白了如何轻松地开始在C++中使用string.find()方法。如果您有任何疑问,请在下方的评论区提出!

另外,在我们的教程部分还有关于 C++ 的其他文章,可以随便看看!


参考文献

  • cppreference.com page on using string find() in C++
  • StackOverflow question on string find()

发表回复 0

Your email address will not be published. Required fields are marked *


广告
将在 10 秒后关闭
bannerAds