Überprüfen Sie, ob eine Zeichenfolge eine Zeichenfolge in C ++ enthält


493

Ich habe eine Variable vom Typ std::string. Ich möchte überprüfen, ob es eine bestimmte enthält std::string. Wie würde ich das machen?

Gibt es eine Funktion, die true zurückgibt, wenn die Zeichenfolge gefunden wird, und false, wenn dies nicht der Fall ist?


6
Meinen Sie char * string oder den String aus der STL?
Anthares

1
Es ist keine Zeichenfolge. Ich musste #include <string> einschließen, um es zu verwenden.
Neuromancer

1
Einige der Lösungen verwenden s2 für die Zeichenfolge, die ich finden möchte. Funktioniert es immer noch, wenn ich etwas wie "Dies ist ein String" anstelle von s2 verwende?
Neuromancer

2
Ja, da es einen String-Literl-Konstruktor für den Typ std :: string gibt.

18
Jemand macht bitte einen Vorschlag, um std::basic_string::containszur stdlib hinzuzufügen.
Emlai

Antworten:


722

Verwenden Sie std::string::findwie folgt:

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

Hinweis: "gefunden!" wird gedruckt, wenn s2es sich um eine Teilzeichenfolge von s1beiden handelt s1und s2vom Typ ist std::string.


117

Sie können versuchen, die findFunktion zu verwenden:

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

if (str.find(str2) != string::npos) {
//.. found.
} 

27

Eigentlich können Sie versuchen, die Boost-Bibliothek zu verwenden. Ich denke, std :: string bietet nicht genügend Methoden, um alle gängigen String-Operationen auszuführen. Beim Boost können Sie einfach Folgendes verwenden 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;
}

33
"Ich denke, std :: string bietet nicht genügend Methoden, um alle gängigen String-Operationen auszuführen." Es gibt jedoch eine findMethode für genau die betreffende Aufgabe. Es ist nicht erforderlich, eine Bibliotheksabhängigkeit einzuführen.
Stefan

8
@stefan, Sie haben Recht, es gibt eine Suchmethode, aber was ist mit Teilen, Ersetzen und vielen anderen Mitarbeitern. Sie können std :: string mit der String-API in Java vergleichen. PS: Auch ich denke, enthält enthält viel eleganter als Suchen Sie, um zu überprüfen, ob eine Zeichenfolge eine andere Zeichenfolge enthält.
Geng Jiawen

1
Auch dies ist kurz und leichter zu speichern. Cpp 17 bietet Unterstützung für das Dateisystem. Ich hoffe, Cpp 2x wird auch etwas für den String tun. Es ist sehr schmerzhaft, in modernen CPP keine grundlegende Unterstützung für String-Methoden zu haben.
Geng Jiawen

1
Benötigen Sie wirklich die "Verwendungen"? Wenn ich diesen Code lese, habe ich keine Ahnung, ob dies der Fall containsist std::containsoder nicht boost::contains, was ein erheblicher Nachteil zu sein scheint. Ich denke, std :: enthält derzeit nicht, aber ich bin nicht sicher, ob es vernünftig ist anzunehmen, dass der Leser alles gespeichert hat, was in std enthalten ist. Und std::containskönnte sehr gut in einer zukünftigen Version von c ++ existieren, die dieses Programm brechen würde.
Don Hatch

12

Sie können dies versuchen

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

4

Für den Fall, dass die Funktionalität für Ihr System kritisch ist, ist es tatsächlich vorteilhaft, eine alte strstrMethode zu verwenden. Die std::searchMethode algorithmist so langsam wie möglich. Ich vermute, dass das Erstellen dieser Iteratoren viel Zeit in Anspruch nimmt.

Der Code, mit dem ich das Ganze zeitlich festgelegt habe, ist

#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;
}

Hier generiere ich zufällig haystacksund suche in ihnen die needle. Die Anzahl der Heuhaufen wird festgelegt, aber die Länge der Saiten in jedem Heuhaufen wird von 10 am Anfang auf 10240 am Ende erhöht. Die meiste Zeit verbringt das Programm damit, zufällige Zeichenfolgen zu generieren, aber das ist zu erwarten.

Die Ausgabe ist:

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.

Die kürzere Version der Antwort lautet: Verwenden von c anstelle von c ++ :)
r0ng

3

Wenn Sie keine Standardbibliotheksfunktionen verwenden möchten, finden Sie unten eine Lösung.

#include <iostream>
#include <string>

bool CheckSubstring(std::string firstString, std::string secondString){
    if(secondString.size() > firstString.size())
        return false;

    for (int i = 0; i < firstString.size(); i++){
        int j = 0;
        // If the first characters match
        if(firstString[i] == secondString[j]){
            int k = i;
            while (firstString[i] == secondString[j] && j < secondString.size()){
                j++;
                i++;
            }
            if (j == secondString.size())
                return true;
            else // Re-initialize i to its original value
                i = k;
        }
    }
    return false;
}

int main(){
    std::string firstString, secondString;

    std::cout << "Enter first string:";
    std::getline(std::cin, firstString);

    std::cout << "Enter second string:";
    std::getline(std::cin, secondString);

    if(CheckSubstring(firstString, secondString))
        std::cout << "Second string is a substring of the frist string.\n";
    else
        std::cout << "Second string is not a substring of the first string.\n";

    return 0;
}

6
Sie verwenden bereits std :: string, daher hängt Ihr Code bereits von std lib ab. Ich sehe keinen Grund, die akzeptierte Lösung mit std :: string :: find zu vermeiden.
b00n12

Ja, das ist ein guter Punkt. Das habe ich nicht gedacht, als ich das geschrieben habe. Ich denke, was ich dachte, als ich das schrieb, war vielleicht, wie man die Verwendung von std :: find einfach vermeidet.
Testing123

3
Nur für zukünftige Besucher: Dieser Algorithmus ist eigentlich nicht korrekt. Da "i" nach einer fehlgeschlagenen Teilzeichenfolgenübereinstimmung nie mehr zurückkehrt, stimmen einige Fälle nicht überein. Beachten Sie beispielsweise: aaabc, aab
sAm_vdP

1
Dies hat mehrere Fehler. CheckSubstring(std::string firstString, std::string secondString)Deep kopiert beide Zeichenfolgen, die an die Funktion übergeben wurden, was teuer ist, insbesondere für längere Zeichenfolgen, die Heap-Zuweisungen erfordern. Ferner sagen Sie rufen CheckSubstring("XYZab", "ab\0\0")- die whileSchleife wird am Ende Vergleich azu a, bum bdie implizite NUL am Ende der ersten Zeichenfolge an den expliziten NUL in den zweiten, dann wird es über die ersten String-Puffer zu lesen, nicht definiertes Verhalten aufweist. Verwenden Sie zum for (... Korrigieren i <= firstString.size () - secondString (). Size (); ...) `.
Tony Delroy

1

Wenn die Größe der Zeichenfolgen relativ groß ist (Hunderte von Bytes oder mehr) und c ++ 17 verfügbar ist, können Sie den Boyer-Moore-Horspool-Sucher verwenden (Beispiel von 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";
}

3
Die Zeichen der Zeit. Früher hätte jemand eine Funktion angeboten bool contains(const std::string& haystack, const std::string& needle). Heutzutage bieten sie eine Reihe von Puzzleteilen an, die nach einigen obskuren Autoren obskurer Papiere benannt sind, damit sie eher wie Informatik aussehen ...
BitTickler

0

Sie können auch den System-Namespace verwenden. Dann können Sie die Methode includes verwenden.

#include <iostream>
using namespace System;

int main(){
    String ^ wholeString = "My name is Malindu";

    if(wholeString->ToLower()->Contains("malindu")){
        std::cout<<"Found";
    }
    else{
        std::cout<<"Not Found";
    }
}

Diese Antwort gilt nur für die proprietäre C ++ - Erweiterung von Microsoft, entweder C ++ / CX oder C ++ / CLI
H. Al-Amri

1
Ja, es tut mir leid, ich wusste nicht, dass es nur so funktioniert, bis ich es irgendwann poste.
Malindu Dilanka

-1

Dies ist eine einfache Funktion

bool find(string line, string sWord)
{
    bool flag = false;
    int index = 0, i, helper = 0;
    for (i = 0; i < line.size(); i++)
    {
        if (sWord.at(index) == line.at(i))
        {
            if (flag == false)
            {
                flag = true;
                helper = i;
            }
            index++;
        }
        else
        {
            flag = false;
            index = 0;
        }
        if (index == sWord.size())
        {
            break;
        }
    }
    if ((i+1-helper) == index)
    {
        return true;
    }
    return false;
}

4
Hallo, willkommen bei SO. Könnten Sie bitte Ihre Antwort bearbeiten und einen Kommentar dazu hinzufügen, wie sie funktioniert und wie sie sich von anderen Antworten unterscheidet? Vielen Dank!
Fabio sagt Reinstate Monica

-1
#include <algorithm>        // std::search
#include <string>
using std::search; using std::count; using std::string;

int main() {
    string mystring = "The needle in the haystack";
    string str = "needle";
    string::const_iterator it;
    it = search(mystring.begin(), mystring.end(), 
                str.begin(), str.end()) != mystring.end();

    // if string is found... returns iterator to str's first element in mystring
    // if string is not found... returns iterator to mystring.end()

if (it != mystring.end())
    // string is found
else
    // not found

return 0;
}

11
Bitte versuchen Sie zu vermeiden, nur Code als Antwort auszugeben, und versuchen Sie zu erklären, was er tut und warum. Ihr Code ist möglicherweise nicht offensichtlich für Personen, die nicht über die entsprechende Codierungserfahrung verfügen. Bitte bearbeiten Sie Ihre Antwort, um Klarstellung und Kontext aufzunehmen, und versuchen Sie, Einschränkungen, Annahmen oder Vereinfachungen in Ihrer Antwort zu erwähnen.
Am 21.

Vielen Dank, dass Sie den Code klargestellt haben, usingnur die erforderlichen Funktionen verwenden und nicht den gesamten Namespace in den globalen Bereich kopieren. Was den @ SᴀᴍOnᴇᴌᴀ-Kommentar betrifft, denke ich, dass der Benutzer die Kommentare in Ihrem Code nicht gelesen hat.
v010dya

-2

Aus so vielen Antworten auf dieser Website habe ich keine klare Antwort herausgefunden, also habe ich in 5-10 Minuten die Antwort selbst herausgefunden. Dies kann jedoch in zwei Fällen erfolgen:

  1. Entweder KENNEN Sie die Position der Teilzeichenfolge, nach der Sie in der Zeichenfolge suchen
  2. Entweder kennen Sie die Position nicht und suchen danach, char by char ...

Nehmen wir also an, wir suchen nach der Teilzeichenfolge "cd" in der Zeichenfolge "abcde" und verwenden die einfachste in C ++ integrierte Funktion " substr"

für 1:

#include <iostream>
#include <string>

    using namespace std;
int i;

int main()
{
    string a = "abcde";
    string b = a.substr(2,2);    // 2 will be c. Why? because we start counting from 0 in a string, not from 1.

    cout << "substring of a is: " << b << endl;
    return 0;
}

für 2:

#include <iostream>
#include <string>

using namespace std;
int i;

int main()
{
    string a = "abcde";

    for (i=0;i<a.length(); i++)
    {
        if (a.substr(i,2) == "cd")
        {
        cout << "substring of a is: " << a.substr(i,2) << endl;    // i will iterate from 0 to 5 and will display the substring only when the condition is fullfilled 
        }
    }
    return 0;
}

2
Inwiefern war die Top-Antwort ("use std :: string :: find"), die 8 Jahre zuvor veröffentlicht wurde, nicht klar genug?
Steve Smith

-3

Wir können stattdessen diese Methode verwenden. Nur ein Beispiel aus meinen Projekten. Beziehen Sie sich auf den Code. Einige Extras sind ebenfalls enthalten.

Schauen Sie sich die if-Anweisungen an!

/*
Every C++ program should have an entry point. Usually, this is the main function.
Every C++ Statement ends with a ';' (semi-colon)
But, pre-processor statements do not have ';'s at end.
Also, every console program can be ended using "cin.get();" statement, so that the console won't exit instantly.
*/

#include <string>
#include <bits/stdc++.h> //Can Use instead of iostream. Also should be included to use the transform function.

using namespace std;
int main(){ //The main function. This runs first in every program.

    string input;

    while(input!="exit"){
        cin>>input;
        transform(input.begin(),input.end(),input.begin(),::tolower); //Converts to lowercase.

        if(input.find("name") != std::string::npos){ //Gets a boolean value regarding the availability of the said text.
            cout<<"My Name is AI \n";
        }

        if(input.find("age") != std::string::npos){
            cout<<"My Age is 2 minutes \n";
        }
    }

}

Es tut mir leid, ich habe nicht gesehen, dass jemand dasselbe gepostet hat, was ich zuvor getan habe.
Malindu Dilanka

1
"Abonniere mich auf YouTube" kann als Spam angesehen werden. Bitte denken Sie in Zukunft daran. Lesen Sie auch Wie man antwortet und wie man kein Spammer ist
Zoe
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.