C ++에서 문자열에 문자열이 포함되어 있는지 확인


493

유형의 변수가 std::string있습니다. 특정 포함되어 있는지 확인하고 싶습니다 std::string. 어떻게해야합니까?

문자열이 발견되면 true를 반환하고 그렇지 않으면 false를 반환하는 함수가 있습니까?


6
char * 문자열 또는 STL의 문자열을 의미합니까?
anthares

1
char * 문자열이 아닙니다. 사용하려면 #string을 포함시켜야했습니다.
neuromancer

1
해결책 중 일부는 찾으려는 문자열에 s2를 사용하고 있습니다. s2 대신 "this is a string"과 같은 것을 사용하면 여전히 작동합니까?
neuromancer

2
std :: string 유형에 대한 문자열 리터럴 생성자가 있기 때문에 그렇습니다.

18
누군가 std::basic_string::containsstdlib 에 추가 할 제안을하십시오 .
emlai

답변:


722

다음 std::string::find과 같이 사용하십시오 .

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

참고 : "발견!" s2하위 문자열이 s1모두 s1s2유형 인 경우 인쇄됩니다 std::string.


117

find기능을 사용해보십시오 .

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

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

27

실제로, 당신은 부스트 ​​라이브러리를 사용하려고 시도 할 수 있습니다 .std :: string은 모든 일반적인 문자열 연산을 수행하기에 충분한 방법을 제공하지 않는다고 생각합니다 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
"std :: string이 모든 일반적인 문자열 연산을 수행하기에 충분한 방법을 제공하지 못한다고 생각합니다." 그러나 문제가 find되는 작업을위한 방법이 있습니다. 라이브러리 의존성을 도입 할 필요가 없습니다.
스테판

8
@ stefan, 맞아요, 찾기 방법이 있지만 split, replace 및 많은 다른 직원은 어떻습니까? 표준 std :: string을 Java의 문자열 api와 비교할 수 있습니다 .PS : 또한 포함하는 것이보다 우아하다고 생각합니다 문자열에 다른 문자열이 포함되어 있는지 확인하십시오.
Geng Jiawen

1
또한 이것은 짧고 기억하기 쉽습니다. Cpp 17은 파일 시스템을 추가로 지원합니다. Cpp 2x가 문자열을 위해 무언가를하기를 바랍니다. 현대 cpp에서 기본 문자열 메소드 지원이 매우 고통 스럽습니다.
Geng Jiawen

1
정말로 "사용"이 필요합니까? 이 코드를 읽을 때 containsis std::contains또는 인지 여부 는 모릅니다 boost::contains. 이는 중대한 단점처럼 보입니다. std :: contains가 현재 존재하지 않는다고 생각하지만 독자가 std에있는 모든 것을 암기했다고 가정하는 것이 합리적입니다. 그리고 std::contains미래의 일부 C ++ 버전에는이 프로그램이 손상 될 수 있습니다.
Don Hatch

12

당신은 이것을 시도 할 수 있습니다

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

4

기능이 시스템에 중요한 경우에는 기존 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;
}

여기 haystacks에서 무작위로 생성 하고 검색합니다 needle. 건초 더미 수는 설정되지만 각 건초 더미 내의 문자열 길이는 처음 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.

대답의 짧은 버전입니다 : 대신 : C ++의 C를 사용하여
r0ng

3

표준 라이브러리 함수를 사용하지 않으려면 아래의 솔루션이 있습니다.

#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
이미 std :: string을 사용하고 있으므로 코드는 이미 std lib에 의존합니다. std :: string :: find를 사용하여 허용 된 솔루션을 피해야하는 이유를 보지 못했습니다.
b00n12

그래, 좋은 지적이야 내가 이것을 쓸 때 그렇게 생각하지 않았습니다. 필자가 이것을 작성할 때 생각한 것은 아마도 std :: find 사용을 피하는 방법 일 것입니다.
Testing123

3
미래 방문자를위한 것 :이 알고리즘은 실제로 정확하지 않습니다. "내가"결코 다시 실패 하위 문자열 경기 후 이동하지 않기 때문에, 일부의 경우, 예를 들어 고려 일치하지 : aaabc, AAB
sAm_vdP

1
이것은 몇 가지 버그가 있습니다. CheckSubstring(std::string firstString, std::string secondString)deep은 함수에 전달 된 두 문자열을 모두 복사합니다. 특히 힙 할당이 필요한 긴 문자열의 경우 비용이 많이 듭니다. 또한, 당신이 전화를 말한다 CheckSubstring("XYZab", "ab\0\0")더 - while루프는 비교 종료됩니다 aa, b하는 b정의되지 않은 동작을 가지고, 두 번째의 명시 적 NUL에 첫 번째 문자열의 끝에 암시 NUL이, 다음은 첫 번째 문자열의 버퍼를 넘어 읽습니다. 수정하려면 for (... i <= firstString.size ()-secondString (). size (); ...)`.
Tony Delroy

1

문자열 크기가 비교적 크고 (수백 바이트 이상) c ++ 17을 사용할 수있는 경우 Boyer-Moore-Horspool searcher (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
시대의 징조. 옛날에는 누군가가 기능을 제공했을 것 bool contains(const std::string& haystack, const std::string& needle)입니다. 오늘날, 그들은 모호한 논문을 모호하게 만든 일부 저자의 이름을 딴 퍼즐 조각을 제공하여 컴퓨터 과학처럼 보이게합니다 ...
BitTickler

0

시스템 네임 스페이스를 사용할 수도 있습니다. 그런 다음 contains 메소드를 사용할 수 있습니다.

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

이 답변은 Microsoft의 독점 C ++ 확장 (C ++ / CX 또는 C ++ / CLI)에만 적용됩니다.
H. Al-Amri

1
예, 죄송합니다. 게시 한 후 언젠가는 그런 식으로 만 작동한다는 것을 몰랐습니다.
Malindu Dilanka

-1

이것은 간단한 기능입니다

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
안녕하세요, SO에 오신 것을 환영합니다. 당신은 기쁘게 할 수 편집 답변을하고 작동 방법에 대한 논평을 추가하고 어떻게 다른 답변 다르다? 감사합니다!
Fabio에 의하면 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
답변으로 코드를 덤프하지 말고 코드의 기능과 이유를 설명하십시오. 관련 코딩 경험이없는 사람들에게는 코드가 명확하지 않을 수 있습니다. 설명, 맥락
Sᴀᴍ Onᴇᴌᴀ

using필요한 함수 만 사용 하고 전체 네임 스페이스를 전역 공간에 덤프하지 않고 코드를 명확하게 작성해 주셔서 감사 합니다. @ SᴀᴍOnᴇᴌᴀ 주석에 관해서는 사용자가 코드에서 주석을 읽지 않았다고 생각합니다.
v010dya 2018

-2

이 웹 사이트의 많은 답변에서 명확한 답변을 찾지 못했기 때문에 5-10 분 안에 답변을 직접 알아 냈습니다. 그러나 이것은 두 가지 경우에 수행 될 수 있습니다.

  1. 문자열에서 검색하는 하위 문자열의 위치 를 알고 있습니다
  2. 어느 쪽이든 당신은 모르는 위치를 숯불에 의해, 그것을 문자를 검색 ...

따라서 문자열 "abcde"에서 하위 문자열 "cd"를 검색 하고 C ++에서 가장 간단한 substr 내장 함수를 사용한다고 가정하겠습니다.

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

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
8 년 전에 게시 된 최상위 답변 ( "use std :: string :: find")은 어떻게 명확하지 않았습니까?
Steve Smith

-3

대신이 방법을 사용할 수 있습니다. 내 프로젝트의 예일뿐입니다. 코드를 참조하십시오. 일부 엑스트라도 포함되어 있습니다.

if 문을보십시오!

/*
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";
        }
    }

}

죄송합니다. 누군가 내가 이전에했던 것과 같은 것을 게시 한 것을 보지 못했습니다.
Malindu Dilanka 2016 년

1
"YouTube 구독자"는 스팸으로 간주 될 수 있습니다. 앞으로도 명심하십시오. 또한 답변 방법
Zoe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.