Remove_if last character from string

I would like to remove the first and last brackets passed by the reference string. Unfortunately, I am having difficulty removing the first and last elements conditionally. I cannot understand why it remove_ifdoes not work as I expect with iterators.

Demo

#include <iostream>
#include <algorithm>
using namespace std;

void print_wo_brackets(string& str){
    auto detect_bracket = [](char x){ return(')' == x || '(' == x);};
    if (!str.empty()) 
    {
        str.erase(std::remove_if(str.begin(), str.begin() + 1, detect_bracket));
    }
    if (!str.empty()) 
    {
        str.erase(std::remove_if(str.end()-1, str.end(), detect_bracket));
    }
}

int main()
{
    string str = "abc)";
    cout << str << endl;
    print_wo_brackets(str);
    cout << str << endl;


    string str2 = "(abc";
    cout << str2 << endl;
    print_wo_brackets(str2);
    cout << str2 << endl;

    return 0;
}

Output

abc)
ac    <- HERE I expect abc 
(abc 
abc
+4
source share
5 answers

If remove_if returns an enditerator, then you will try to remove the nonexistent element. You must use the version erasefor the range in both places:

void print_wo_brackets(string& str){
    auto detect_bracket = [](char x){ return(')' == x || '(' == x);};
    if (!str.empty())
    {
        str.erase(std::remove_if(str.begin(), str.begin() + 1, detect_bracket), str.begin() + 1);
    }
    if (!str.empty())
    {
        str.erase(std::remove_if(str.end()-1, str.end(), detect_bracket), str.end());
    }
}
+6
source

The problem is here:

if (!str.empty()) 
{
    str.erase(std::remove_if(str.begin(), str.begin() + 1, detect_bracket));
}

. std::remove_if " ". , (str.begin() + 1). , begin+1, b.

, , , - :

if (!str.empty()) 
{
    auto it = std::remove_if(str.begin(), str.begin() + 1, detect_bracket);
    if(it != str.begin() + 1)
        str.erase(it);
}

, , :

if(str[0] == '(' || str[0] == ')')
    str.erase(0);

.

+4

:

#include <iostream>
#include <string>

std::string without_brackets(std::string str, char beg = '(', char end = ')') {
    auto last = str.find_last_of(end);
    auto first = str.find_first_of(beg);

    if(last != std::string::npos) {
        str.erase(str.begin()+last);
    }
    if(first != std::string::npos) {
        str.erase(str.begin()+first);
    }

    return str;
}


using namespace std;

int main() {
    cout << without_brackets("abc)") << endl
         << without_brackets("(abc") << endl
         << without_brackets("(abc)") << endl
         << without_brackets("abc") << endl;
    return 0;
}

. http://ideone.com/T2bZDe

:

abc
abc
abc
abc
+3

@PeteBecker, remove_if . , , - back() front() ( ) ( [ ])

void remove_surrounding(string& str, char left = '(', char right = ')')
{
    if (!str.empty() && str.front() == left)
        str.erase(str.begin());
    if (!str.empty() && str.back() == right)
        str.erase(str.end() - 1);
}

+2
source

All you need is:

void print_wo_brackets(string& str){
  str.erase(std::remove_if(str.begin(), str.end(),
    [&](char &c) { return (c == ')' || c == '(') && (&c == str.data() || &c == (str.data() + str.size() - 1));}), str.end());
}

Live demo

Pointing out:

str.erase(std::remove_if(str.end()-1, str.end(), detect_bracket));

You invoke undefined behavior.

+1
source

All Articles