By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,053 Members | 1,165 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,053 IT Pros & Developers. It's quick & easy.

std::string question

P: n/a
Hello,

I would like to replace all the occurrence of "(" and ")"
in C++ std::string to "\(" and "\)".

For example:
string s = "(abc)|(toto)|(lala)"
will be become "\(abc\)|\(toto\)|\(lala\)"
Question:
Just wonder if there is a straight forward function to do so??
Currently I am using a while loop to read through the string, then
basic_string::find and basic_string::replace the occurrence of "(" and ")".

Any better solution?

Thanks,
Kian
Jul 22 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a

"Kian Goh" <ki**@hotmail.com> wrote in message
news:g_********************@rogers.com...
Hello,

I would like to replace all the occurrence of "(" and ")"
in C++ std::string to "\(" and "\)".

For example:
string s = "(abc)|(toto)|(lala)"
will be become "\(abc\)|\(toto\)|\(lala\)"
Question:
Just wonder if there is a straight forward function to do so??
No.


Currently I am using a while loop to read through the string, then
basic_string::find and basic_string::replace the occurrence of "(" and
")".

Any better solution?


Certainly there are bad ways and good ways to write this code but without
seeing the code you have written it is impossible to say whether there is a
better solution.

A good solution would work in three phases.

1) Go though the string seeing how many backslashes you are going to need to
insert
2) Increase the size of the string by the number of extra backslashes needed
3) Loop backwards though the string, copying characters and inserting
backslashes as necessary.

The point of this compexity is that it minimises reallocation of the string
and copying of characters.

A bad solution would work like this

1) Go forwards through the string and each time you find a "(" or ")" insert
a backslash.

john
Jul 22 '05 #2

P: n/a
"Kian Goh" <ki**@hotmail.com> wrote in message
news:g_********************@rogers.com...
Hello,

I would like to replace all the occurrence of "(" and ")"
in C++ std::string to "\(" and "\)".

For example:
string s = "(abc)|(toto)|(lala)"
will be become "\(abc\)|\(toto\)|\(lala\)"
Question:
Just wonder if there is a straight forward function to do so??
Currently I am using a while loop to read through the string, then
basic_string::find and basic_string::replace the occurrence of "(" and
")".

Any better solution?

Thanks,
Kian


Here is a solution:

string add_backslash_to_brackets(char ch)
{
string s(1, ch);
if (ch == '(' || ch == ')')
s.insert(s.begin(), '\\');
return s;
}

vector<string> v;
transform(s.begin(), s.end(), back_inserter(v), add_backslash_to_brackets);
s = accumulate(v.begin(), v.end(), string());

Hope you like it.
Jul 22 '05 #3

P: n/a
"Jason Heyes" <ja********@optusnet.com.au> wrote in message
news:419b0f0b$0$24380
"Kian Goh" <ki**@hotmail.com> wrote in message
For example:
string s = "(abc)|(toto)|(lala)"
will be become "\(abc\)|\(toto\)|\(lala\)"

string add_backslash_to_brackets(char ch)
{
string s(1, ch);
if (ch == '(' || ch == ')')
s.insert(s.begin(), '\\');
return s;
}

vector<string> v;
transform(s.begin(), s.end(), back_inserter(v), add_backslash_to_brackets); s = accumulate(v.begin(), v.end(), string());


Good.

Along the same lines, the function back_inserter(v) returns an iterator,
specifically a std::back_insert_iterator<std::vector<std::string> >, whose
operator= calls v.push_back(...). You could write your own
back_insert_iterator class too, thus avoiding the need to create strings and
a vector of strings.

class special_back_insert_iterator : public
std::back_insert_iterator<std::string> {
typedef std::back_insert_iterator<std::string> inherited;
public:
special_back_insert_iterator(std::string& s) : inherited(s) { }
special_back_insert_iterator& operator=(char c) {
if (ch == '(' || ch == ')') inherited::operator=('\\');
inherited::operator==(c);
return *this;
}
};

inline
special_back_insert_iterator special_back_inserter(std::string&)
{
return ...;
}

string s2;
transform(s.begin(), s.end(), special_back_inserter(s2));
Jul 22 '05 #4

P: n/a
"Siemel Naran" <Si*********@REMOVE.att.net> wrote in message
news:nx*******************@bgtnsc05-news.ops.worldnet.att.net...
"Jason Heyes" <ja********@optusnet.com.au> wrote in message
news:419b0f0b$0$24380
"Kian Goh" <ki**@hotmail.com> wrote in message

> For example:
> string s = "(abc)|(toto)|(lala)"
> will be become "\(abc\)|\(toto\)|\(lala\)"

string add_backslash_to_brackets(char ch)
{
string s(1, ch);
if (ch == '(' || ch == ')')
s.insert(s.begin(), '\\');
return s;
}

vector<string> v;
transform(s.begin(), s.end(), back_inserter(v),

add_backslash_to_brackets);
s = accumulate(v.begin(), v.end(), string());


Good.

Along the same lines, the function back_inserter(v) returns an iterator,
specifically a std::back_insert_iterator<std::vector<std::string> >, whose
operator= calls v.push_back(...). You could write your own
back_insert_iterator class too, thus avoiding the need to create strings
and
a vector of strings.

class special_back_insert_iterator : public
std::back_insert_iterator<std::string> {
typedef std::back_insert_iterator<std::string> inherited;
public:
special_back_insert_iterator(std::string& s) : inherited(s) { }
special_back_insert_iterator& operator=(char c) {
if (ch == '(' || ch == ')') inherited::operator=('\\');
inherited::operator==(c);
return *this;
}
};

inline
special_back_insert_iterator special_back_inserter(std::string&)
{
return ...;
}

string s2;
transform(s.begin(), s.end(), special_back_inserter(s2));


Nice. It all happens in one line of STL. I wonder how these STL solutions
compare with non-STL ones in terms of code complexity. Alot better I
presume.
Jul 22 '05 #5

P: n/a
On Tue, 16 Nov 2004 21:59:27 -0500 in comp.lang.c++, "Kian Goh"
<ki**@hotmail.com> wrote,
I would like to replace all the occurrence of "(" and ")"
in C++ std::string to "\(" and "\)".

#include <string>
#include <algorithm>
#include <numeric>
#include <iostream>

std::string changer(std::string was, char in)
{
if (in == '(')
return was+"\\(";
if (in == ')')
return was+"\\)";
return was+in;
};

int main()
{
std::string foo("(abc)|(toto)|(lala)");
std::string bar = std::accumulate(foo.begin(), foo.end(),
std::string(""), changer);
std::cout << bar;
}

Jul 22 '05 #6

P: n/a
"Jason Heyes" <ja********@optusnet.com.au> wrote in message
news:419b27d6$0$27445
"Siemel Naran" <Si*********@REMOVE.att.net> wrote in message

string s2;
transform(s.begin(), s.end(), special_back_inserter(s2));


Nice. It all happens in one line of STL. I wonder how these STL solutions
compare with non-STL ones in terms of code complexity. Alot better I
presume.


Except for the meaningless name 'special_back_inserter', the code above
looks simpler. However, it's not an inplace algorithm, therefore uses more
memory. John's suggestion is in in-place algorithm, though harder to
implement.
Jul 22 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.