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

时间:2020-02-23 14:30:06  来源:igfitidea点击:

在本文中,我们将研究如何在C++中使用String find()。

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

C++中String find()的语法

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

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

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

这样,该函数的定义如下:

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

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

默认情况下为0,因此,除非您明确指定起始位置,否则搜索将从字符串的开头开始。

还要注意,该字符串是通过const引用传递的。

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

注意:从C++ 20开始,许多标准库方法现在都兼容constexpr,因此它们是在编译时本身执行的。
您可以在线阅读有关constexpr复杂性的更多信息。

有几个函数重载,由于您可以在此页面上找到更多信息,因此我将跳过其中的大多数。
相反,我们将重点放在一种涉及子字符串长度的特定重载上。

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

这种特殊的重载检查子字符串是否位于我们的字符串内,但它也对子字符串长度有限制。
这将匹配到" 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 theitroad");
  //Target string to search for
  std::string target_string("theitroad");

  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 theitroad a substring of Hello from theitroad ?
Length of matched substring = 11

如您所见,子字符串确实存在于我们原始字符串中!

现在,从字符串的特定位置搜索相同的子字符串。

#include <iostream>
#include <string>

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

  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 theitroad a substring of Hello from theitroad ?
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 theitroad");
  //Target string to search for
  std::string target_string("theitroad");

  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 theitroad a substring of Hello from theitroad ?
No

现在,由于我们从索引12开始,我们获得了预期的输出!

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

#include <iostream>
#include <string>

int main() {
  //Create our string
  std::string my_str("Hello from theitroad");
  //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 theitroad ?
Length of matched substring = 11

请注意,我们已经更改了目标字符串。
其中尽管只有前5个字符会被匹配,但这对于find()就足够了,因为我们将计数器限制为5!

因此,它将仅忽略目标子字符串的其余部分,并继续匹配我们的原始字符串,直到字符串结尾!

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