检查字符串是否包含C++中的字符串

neu*_*cer 447 c++ string substring

我有一个类型的变量std::string.我想检查它是否包含某些内容std::string.我该怎么办?

是否有一个函数在找到字符串时返回true,如果不是则返回false?

小智 647

使用std::string::find方法如下:

if (s1.find(s2) != std::string::npos) {
    std::cout << "found!" << '\n';
}
Run Code Online (Sandbox Code Playgroud)

注意:"找到了!" 将打印如果s2是子串s1,两者s1s2类型std::string.

  • 尝试查找子字符串时 std::string::find 返回什么? (2认同)
  • 它返回从给定起始位置开始子字符串在字符串中第一次出现的索引。起始位置的默认值为 0。 (2认同)
  • 根据 C++ 文档 std::string::npos 为 -1。如果没有匹配则 find 函数返回 -1。如果存在匹配,则返回出现的索引,该索引始终为正数。这就是为什么我们在这里做 != -1 检查 (2认同)

cod*_*ict 106

您可以尝试使用该find功能:

string str ("There are two needles in this haystack.");
string str2 ("needle");

if (str.find(str2) != string::npos) {
//.. found.
} 
Run Code Online (Sandbox Code Playgroud)


Syn*_*nck 32

从 C++23 开始,您可以使用std::string::contains

#include <string>

const auto haystack = std::string("haystack with needles");
const auto needle = std::string("needle");

if (haystack.contains(needle))
{
    // found!
}
Run Code Online (Sandbox Code Playgroud)

  • 令我惊讶的是,在这一切发生之前我们必须达到 C++23。 (34认同)
  • @alfC 它和它看起来一样有用 - 它告诉你一个字符串是否包含某个子字符串/字符。通常这就是您所需要的。如果你关心它的位置,那么你会使用“find”来告诉你它的位置。 (8认同)
  • 要了解它存在的原因,请查看[此处](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1679r0.html#:~:text=A%20contains%20member %20函数%20会,%20程序员的%20意图%20。) (2认同)

Gen*_*wen 24

实际上,你可以尝试使用boost库,我认为std :: string没有提供足够的方法来完成所有常见的字符串操作.在boost中,你可以只使用boost::algorithm::contains:

#include <string>
#include <boost/algorithm/string.hpp>

int main() {
    std::string s("gengjiawen");
    std::string t("geng");
    bool b = boost::algorithm::contains(s, t);
    std::cout << b << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • "我认为std :: string没有提供足够的方法来完成所有常见的字符串操作".但是有一个`find`方法可以完全解决相关任务.无需引入库依赖项. (28认同)
  • @stefan,你是对的,有一个find方法,但是如何分割,替换和许多其他staff.you可以比较std :: string到Java.PS中的字符串api:我也认为包含比它更优雅找到检查字符串是否包含另一个字符串. (7认同)
  • 您真的需要“使用”吗?当我阅读这段代码时,我不知道“contains”是“std::contains”还是“boost::contains”,这似乎是一个重大缺点。我猜 std::contains 目前不存在,但我不确定假设读者已经记住了 std 中的所有内容是否合理。并且 `std::contains` 很可能存在于 C++ 的某个未来版本中,这会破坏这个程序。 (2认同)

v01*_*dya 11

如果该功能对您的系统至关重要,那么使用旧strstr方法实际上是有益的。里面的std::search方法algorithm是最慢的。我的猜测是创建这些迭代器需要很多时间。

我用来计时的代码是

#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <random>
#include <chrono>

std::string randomString( size_t len );

int main(int argc, char* argv[])
{
        using namespace std::chrono;

        const size_t haystacksCount = 200000;
        std::string haystacks[haystacksCount];
        std::string needle = "hello";

        bool sink = true;

        high_resolution_clock::time_point start, end;
        duration<double> timespan;

        int sizes[10] = { 10, 20, 40, 80, 160, 320, 640, 1280, 5120, 10240 };

        for(int s=0; s<10; ++s)
        {
                std::cout << std::endl << "Generating " << haystacksCount << " random haystacks of size " << sizes[s] << std::endl;
                for(size_t i=0; i<haystacksCount; ++i)
                {
                        haystacks[i] = randomString(sizes[s]);
                }

                std::cout << "Starting std::string.find approach" << std::endl;
                start = high_resolution_clock::now();
                for(size_t i=0; i<haystacksCount; ++i)
                {
                        if(haystacks[i].find(needle) != std::string::npos)
                        {
                                sink = !sink; // useless action
                        }
                }
                end = high_resolution_clock::now();
                timespan = duration_cast<duration<double>>(end-start);
                std::cout << "Processing of " << haystacksCount << " elements took " << timespan.count() << " seconds." << std::endl;

                std::cout << "Starting strstr approach" << std::endl;
                start = high_resolution_clock::now();
                for(size_t i=0; i<haystacksCount; ++i)
                {
                        if(strstr(haystacks[i].c_str(), needle.c_str()))
                        {
                                sink = !sink; // useless action
                        }
                }
                end = high_resolution_clock::now();
                timespan = duration_cast<duration<double>>(end-start);
                std::cout << "Processing of " << haystacksCount << " elements took " << timespan.count() << " seconds." << std::endl;

                std::cout << "Starting std::search approach" << std::endl;
                start = high_resolution_clock::now();
                for(size_t i=0; i<haystacksCount; ++i)
                {
                        if(std::search(haystacks[i].begin(), haystacks[i].end(), needle.begin(), needle.end()) != haystacks[i].end())
                        {
                                sink = !sink; // useless action
                        }
                }
                end = high_resolution_clock::now();
                timespan = duration_cast<duration<double>>(end-start);
                std::cout << "Processing of " << haystacksCount << " elements took " << timespan.count() << " seconds." << std::endl;
        }

        return 0;
}

std::string randomString( size_t len)
{
        static const char charset[] = "abcdefghijklmnopqrstuvwxyz";
        static const int charsetLen = sizeof(charset) - 1;
        static std::default_random_engine rng(std::random_device{}());
        static std::uniform_int_distribution<> dist(0, charsetLen);
        auto randChar = [charset, &dist, &rng]() -> char
        {
                return charset[ dist(rng) ];
        };

        std::string result(len, 0);
        std::generate_n(result.begin(), len, randChar);
        return result;
}
Run Code Online (Sandbox Code Playgroud)

在这里,我生成随机haystacks并在其中搜索needle. 设置了haystack数,但是每个haystack内的字符串长度从开始的10个增加到最后的10240个。大部分时间该程序实际上花费在生成随机字符串上,但这是意料之中的。

输出是:

Generating 200000 random haystacks of size 10
Starting std::string.find approach
Processing of 200000 elements took 0.00358503 seconds.
Starting strstr approach
Processing of 200000 elements took 0.0022727 seconds.
Starting std::search approach
Processing of 200000 elements took 0.0346258 seconds.

Generating 200000 random haystacks of size 20
Starting std::string.find approach
Processing of 200000 elements took 0.00480959 seconds.
Starting strstr approach
Processing of 200000 elements took 0.00236199 seconds.
Starting std::search approach
Processing of 200000 elements took 0.0586416 seconds.

Generating 200000 random haystacks of size 40
Starting std::string.find approach
Processing of 200000 elements took 0.0082571 seconds.
Starting strstr approach
Processing of 200000 elements took 0.00341435 seconds.
Starting std::search approach
Processing of 200000 elements took 0.0952996 seconds.

Generating 200000 random haystacks of size 80
Starting std::string.find approach
Processing of 200000 elements took 0.0148288 seconds.
Starting strstr approach
Processing of 200000 elements took 0.00399263 seconds.
Starting std::search approach
Processing of 200000 elements took 0.175945 seconds.

Generating 200000 random haystacks of size 160
Starting std::string.find approach
Processing of 200000 elements took 0.0293496 seconds.
Starting strstr approach
Processing of 200000 elements took 0.00504251 seconds.
Starting std::search approach
Processing of 200000 elements took 0.343452 seconds.

Generating 200000 random haystacks of size 320
Starting std::string.find approach
Processing of 200000 elements took 0.0522893 seconds.
Starting strstr approach
Processing of 200000 elements took 0.00850485 seconds.
Starting std::search approach
Processing of 200000 elements took 0.64133 seconds.

Generating 200000 random haystacks of size 640
Starting std::string.find approach
Processing of 200000 elements took 0.102082 seconds.
Starting strstr approach
Processing of 200000 elements took 0.00925799 seconds.
Starting std::search approach
Processing of 200000 elements took 1.26321 seconds.

Generating 200000 random haystacks of size 1280
Starting std::string.find approach
Processing of 200000 elements took 0.208057 seconds.
Starting strstr approach
Processing of 200000 elements took 0.0105039 seconds.
Starting std::search approach
Processing of 200000 elements took 2.57404 seconds.

Generating 200000 random haystacks of size 5120
Starting std::string.find approach
Processing of 200000 elements took 0.798496 seconds.
Starting strstr approach
Processing of 200000 elements took 0.0137969 seconds.
Starting std::search approach
Processing of 200000 elements took 10.3573 seconds.

Generating 200000 random haystacks of size 10240
Starting std::string.find approach
Processing of 200000 elements took 1.58171 seconds.
Starting strstr approach
Processing of 200000 elements took 0.0143111 seconds.
Starting std::search approach
Processing of 200000 elements took 20.4163 seconds.
Run Code Online (Sandbox Code Playgroud)

  • 答案的简短版本是:使用 c 而不是 c++ :) (3认同)

Hap*_*ran 10

你可以试试这个

string s1 = "Hello";
string s2 = "el";
if(strstr(s1.c_str(),s2.c_str()))
{
   cout << " S1 Contains S2";
}
Run Code Online (Sandbox Code Playgroud)

  • 凉爽的。这很快,即 1μs。而 `data.find(needle) != string::npos` 在我的机器上需要 4μs。 (2认同)

Kon*_*nik 7

如果字符串的大小相对较大(数百字节或更多)并且 c++17 可用,您可能需要使用 Boyer-Moore-Horspool 搜索器(来自 cppreference.com 的示例):

#include <iostream>
#include <string>
#include <algorithm>
#include <functional>

int main()
{
    std::string in = "Lorem ipsum dolor sit amet, consectetur adipiscing elit,"
                     " sed do eiusmod tempor incididunt ut labore et dolore magna aliqua";
    std::string needle = "pisci";
    auto it = std::search(in.begin(), in.end(),
                   std::boyer_moore_searcher(
                       needle.begin(), needle.end()));
    if(it != in.end())
        std::cout << "The string " << needle << " found at offset "
                  << it - in.begin() << '\n';
    else
        std::cout << "The string " << needle << " not found\n";
}
Run Code Online (Sandbox Code Playgroud)

  • 时代的痕迹。在过去,有人会提供一个函数“bool contains(const std::string&amp; haystack, const std::string&amp; Needle)”。如今,他们提供了一组以一些不起眼论文作者的名字命名的拼图,使其看起来更像计算机科学...... (25认同)

jer*_*naa 6

关于什么

string response = "hello world";
string findMe = "world";

if(response.find(findMe) != string::npos)
{
     //found
}
Run Code Online (Sandbox Code Playgroud)