pabitra mohan
pabitra mohan

Reputation: 87

Can we remove two substrings from a C++ string simultaneously?

Assume I have a C++ string /dev/class/xyz1/device/vendor/config. As a part of my work, I am required to remove substrings "device" and "config" from the above string.

I know I can accomplish it by using "erase" call twice. But, I was wondering if this can be achieved in a single call. Any string class library call or boost call to achieve this?

Upvotes: 1

Views: 103

Answers (2)

Xaser
Xaser

Reputation: 2146

Other than Regular Expressions, I'm not aware of any other method.

However think about why you want to do this. Just because it's a single call won't make it "alot" faster, as the code still needs to be executed one way or the other.

On the other hand, having a command for each word would increase code-readability, which always should be high-priority.

If you need this often and want to save lines, you could however easily write such a function yourself, and put it into a library of your custom utility functions. The function could take the input string and a std::vector for strings or any other form of string-collection to remove from the prior.

Upvotes: 2

sehe
sehe

Reputation: 392833

It's not entirely clear how specific the algorithm should be. But, for the case given, the following would have minimum copying and do the mutation "atomically" (as in: either both or no substrings removed):

namespace ba = boost::algorithm;

void mutate(std::string& the_string) {
    if (ba::ends_with(the_string, "/config")) {
        auto pos = the_string.find("/device/");
        if (std::string::npos != pos) {
            the_string.resize(the_string.size() - 7); // cut `/config`
            the_string.erase(pos, 7);                 // cut `/device`
        }
    }
}

See it Live On Coliru

#include <boost/algorithm/string.hpp>

namespace ba = boost::algorithm;

void mutate(std::string& the_string) {
    if (ba::ends_with(the_string, "/config")) {
        auto pos = the_string.find("/device/");
        if (std::string::npos != pos) {
            the_string.resize(the_string.size() - 7); // cut `/config`
            the_string.erase(pos, 7);                 // cut `/device`
        }
    }
}

#include <iostream>

int main() {
    std::string s = "/dev/class/xyz1/device/vendor/config";
    std::cout << "before:  " << s << "\n";
    mutate(s);
    std::cout << "mutated: " << s << "\n";
}

Prints

before:  /dev/class/xyz1/device/vendor/config
mutated: /dev/class/xyz1/vendor

Upvotes: 0

Related Questions