AKSHAY JAIN
AKSHAY JAIN

Reputation: 43

How to extract a substring from string beginning to the second delimiter?

My string is: std::string achRecBuff = "usbaudio_1_req:some string";

From that string, I want to extract the string till the second delimiter '_'. So the extracted string should be like "usbaudio_1".

How can I do that?

Upvotes: 1

Views: 787

Answers (3)

lubgr
lubgr

Reputation: 38267

When the second underscore is always identical to the last underscore, a simple solution looks like this:

const auto pos = achRecBuff.find_last_of('_');

const std::string upTo2ndUnderscore = achRecBuff.substr(0, pos);

Edit: Considering a general case (thanks to @chris for pointing that out), this snippet also does what you want:

template <class Container, class Element>
Container beforeNthMatch(const Container& c, const Element& value, unsigned n)
{
    using std::cbegin;
    using std::cend;
    auto pos = cbegin(c);

    while (n-- != 0) {
        pos = std::find(++pos, cend(c), value);

        if (pos == cend(c))
            return {};
    }

    return {cbegin(c), pos};
}

In your case, the invocation looks like

const std::string upTo2ndUnderscore = beforeNthMatch(achRecBuff, '_', 2);

Cases like empty input containers are covered, and you can also use it with different cotainers, e.g. to find the nth given integer in a std::vector<int>.

Upvotes: 2

Galik
Galik

Reputation: 48605

You can use std::string::find a couple of times like this:

std::string extract_special_part(std::string const& s)
{
    if(auto pos = s.find('_') + 1)
        if((pos = s.find('_', pos)) + 1)
            return s.substr(0, pos);

    return {};
}

int main()
{
    std::string achRecBuff = "usbaudio_1_req:some string";

    std::cout << extract_special_part(achRecBuff) << '\n';
}

Output:

usbaudio_1

It relies on the well defined behavior of std::string::npos to wrap round to zero when you add one to it. If the character is not found then the if() statements fail because std::string::npos + 1 becomes 0 which is false.

Upvotes: 2

Junhee Shin
Junhee Shin

Reputation: 758

#include <iostream>
int main() {
        std::string a="usbaudio_1_req:some string" ;
        std::string::size_type f = a.find("_") ; // find 1st pos
        if ( f!=std::string::npos ) {
                f=a.find("_", f+1) ;    // find 2nd pos
                if ( f!=std::string::npos ) {
                        std::string b = a.substr(0, f) ;
                        std::cout << b << std::endl ;
                }
        }
        return 0 ;
}

the output is

usbaudio_1

Upvotes: 0

Related Questions