Search code examples
c++c++98

How to find a substring in only a portion of a std::string?


I have a std::string and i want to be able to find text only in a section of it : so i need to specify a start and an end position.

In std::string::find() one can only specify the start position.

I am trying to find the best way to search only in a portion of haystack. That would consist of giving an end_pos to stop the search even though it doesn't reach the end of haystack.

For example, search only from its 100th character to its 200th character.

Does anybody know how I could achieve this (elegantly)?

  • only by searching in haystack itself, not in a substr() of it
  • without creating a copy of haystack
  • in C++98

Solution

  • std::string does not have a method that suits your requirement to search a sub-range of the haystack string. Have a look at std::search() for that instead, eg:

    std::string needle = ...;
    
    std::string::iterator end_iter = haystack.begin() + end_pos;
    std::string::iterator found_iter = std::search(haystack.begin() + start_pos, end_iter, needle.begin(), needle.end());
    if (found_iter != end_iter) {
        // needle found...
    }
    else {
        // needle not found...
    }
    

    If your compiler does not have std::search() available, then just write your own search() function, such as with the implementation provided on cppreference.com, eg:

    namespace my {
    
    template<class ForwardIt1, class ForwardIt2>
    ForwardIt1 search(ForwardIt1 first, ForwardIt1 last,
                      ForwardIt2 s_first, ForwardIt2 s_last)
    {
        while (1) {
            ForwardIt1 it = first;
            for (ForwardIt2 s_it = s_first; ; ++it, ++s_it) {
                if (s_it == s_last) return first;
                if (it == last) return last;
                if (!(*it == *s_it)) break;
            }
            ++first;
        }
    }
    
    }
    
    ...
    
    std::string needle = ...;
    
    std::string::iterator end_iter = haystack.begin() + end_pos;
    std::string::iterator found_iter = my::search(haystack.begin() + start_pos, end_iter, needle.begin(), needle.end());
    if (found_iter != end_iter) {
        // needle found...
    }
    else {
        // needle not found...
    }