I would like to remove first and last brackets in passed by reference string. Unfortunately, I have difficulties with removing first and last elements conditionally.
I cannot understand why remove_if
doesn't 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;
}
abc)
ac <- HERE I expect abc
(abc
abc
The string method rstrip is used to remove the characters from the right side of the string that is given to it. So we will be using it to remove or delete the last character of the string.
Using for loop to Remove Last Character From String in Python We can also use the for loop to remove or delete the last character from the string. We will take out the length of the string from the len () function. Then we will take an empty string.
The StringBuffer class provides a method deleteCharAt (). The method deletes a character from the specified position. We use the method to remove a character from a string in Java.
replace will replace all instances of a letter. All you need to do is use substring (): public String method (String str) { if (str != null && str.length () > 0 && str.charAt (str.length () - 1) == 'x') { str = str.substring (0, str.length () - 1); } return str; } I'd add null != str && at the beginning of the check. you mean str != null &&!
If remove_if returns end
iterator then you will try to erase nonexistent element. You should use erase
version for 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());
}
}
The problem is here:
if (!str.empty())
{
str.erase(std::remove_if(str.begin(), str.begin() + 1, detect_bracket));
}
you erase unconditionally.
std::remove_if
returns iterator to the beginning of range "for removal". If there are no elements for removal, it returns end of range (str.begin() + 1
in this case). So you remove begin+1
element, which is b
.
To protect from this problem you shouldn't probably do something more like:
if (!str.empty())
{
auto it = std::remove_if(str.begin(), str.begin() + 1, detect_bracket);
if(it != str.begin() + 1)
str.erase(it);
}
I assume you simply want to check behavior of standard library and iterators, as otherwise check:
if(str[0] == '(' || str[0] == ')')
str.erase(0);
is much simpler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With