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

Quick std::string question

P: n/a
Let's say I have a std::string, and I want to replace all the ','
characters with " or ", i.e. "A,B,C" -> "A or B or C". Is the
following the best way to do it?

int idx;
while( (idx=str.find_first_of(',')) >= 0 ) {
str.replace( idx, 1, "" );
str.insert( idx, " or " );
}

(Stroustrup wasn't too illuminating here, unfortunately.)

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Jul 22 '05 #1
Share this Question
Share on Google+
11 Replies


P: n/a
On Mon, 9 Feb 2004 21:18:47 +0000 (UTC), Christopher Benson-Manica
<at***@nospam.cyberspace.org> wrote:
Let's say I have a std::string, and I want to replace all the ','
characters with " or ", i.e. "A,B,C" -> "A or B or C". Is the
following the best way to do it?

int idx;
while( (idx=str.find_first_of(',')) >= 0 ) {
str.replace( idx, 1, "" );
str.insert( idx, " or " );
}

(Stroustrup wasn't too illuminating here, unfortunately.)


See if this will work for you:

///
/// Replace all occurences of a substring in a string with another
/// string, in-place.
///
/// @param s String to replace in. Will be modified.
/// @param sub Substring to replace.
/// @param other String to replace substring with.
///
/// @return The string after replacements.
inline std::string &
replacein(std::string &s, const std::string &sub,
const std::string &other)
{
assert(!sub.empty());
size_t b = 0;
for (;;)
{
b = s.find(sub, b);
if (b == s.npos) break;
s.replace(b, sub.size(), other);
b += other.size();
}
return s;
}

--
Be seeing you.
Jul 22 '05 #2

P: n/a
Christopher Benson-Manica wrote:
Let's say I have a std::string, and I want to replace all the ','
characters with " or ", i.e. "A,B,C" -> "A or B or C". Is the
following the best way to do it?

int idx;
while( (idx=str.find_first_of(',')) >= 0 ) {
This will start from the beginning for each ',' that was found and again
search the already searched parts. I'd replace the above two lines
with:

int idx = 0;
while( (idx=str.find_first_of(',', idx)) >= 0 ) {

You could even save a bit more by jumping over the replacement text,
too.
str.replace( idx, 1, "" );
str.insert( idx, " or " );

Why do you first replace the ',' with an empty string and then insert
the " or " instead of just replacing it directly with " or "?

str.replace(idx, 1, " or ");
}

(Stroustrup wasn't too illuminating here, unfortunately.)


--
Never wondered why a carrot is more orange than an orange?

Jul 22 '05 #3

P: n/a
"Christopher Benson-Manica" <at***@nospam.cyberspace.org> wrote in message
news:c0**********@chessie.cirr.com...
Let's say I have a std::string, and I want to replace all the ','
characters with " or ", i.e. "A,B,C" -> "A or B or C". Is the
following the best way to do it?

int idx;
while( (idx=str.find_first_of(',')) >= 0 ) {
str.replace( idx, 1, "" );
str.insert( idx, " or " );
}

(Stroustrup wasn't too illuminating here, unfortunately.)


For more versatility, I've changed your 'character to find'
to 'string to find':
#include <iostream>
#include <string>

/* If 'from' matches 'to' or 'from' is empty, */
/* does not parse 's', returns std::string::npos */
/* */
/* Otherwise returns number of replacements done */
/* */

std::string::size_type repl(std::string& s,
const std::string& from,
const std::string& to)
{
std::string::size_type cnt(std::string::npos);

if(from != to && !from.empty())
{
std::string::size_type pos1(0);
std::string::size_type pos2(0);
const std::string::size_type from_len(from.size());
const std::string::size_type to_len(to.size());
cnt = 0;

while((pos1 = s.find(from, pos2)) != std::string::npos)
{
s.replace(pos1, from_len, to);
pos2 = pos1 + to_len;
++cnt;
}
}

return cnt;
}

int main()
{
std::string s("A,B,C");

const std::string old_seq(",");
const std::string new_seq(" or ");

std::cout << "Original string:\n"
<< '"' << s << '"'
<< "\n\n";

const std::string::size_type count(repl(s, old_seq, new_seq));
const std::string dq(count > 0, '"');
const bool parsed(count != std::string::npos);
const bool found(parsed && count > 0);

if(parsed)
{
std::cout << count
<< " occurences of sequence \"" << old_seq << "\""
<< (count ? " replaced with sequence " : " found")
<< dq << (count ? new_seq : "") << dq
<< "\n\n";
}
else
std::cout << "Nothing to change\n\n";

std::cout << (parsed && found
? std::string("New string:\n" + dq + s + dq)
: "No changes made")
<< '\n';

return 0;
}

Original string:
"A,B,C"

2 occurences of sequence "," replaced with sequence " or "

New string:
"A or B or C"

HTH,
-Mike

Jul 22 '05 #4

P: n/a
"Christopher Benson-Manica" <at***@nospam.cyberspace.org> wrote in message
news:c0**********@chessie.cirr.com...
Let's say I have a std::string, and I want to replace all the ','
characters with " or ", i.e. "A,B,C" -> "A or B or C". Is the
following the best way to do it?

int idx;
while( (idx=str.find_first_of(',')) >= 0 ) {
str.replace( idx, 1, "" );
str.insert( idx, " or " );
}

(Stroustrup wasn't too illuminating here, unfortunately.)

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.


std::string // replace all instances of victim with replacement
mass_replace(const std::string &source, const std::string &victim, const
std::string &replacement)
{
std::string answer = source;
std::string::size_type j = 0;
while ((j = answer.find(victim, j)) != std::string::npos )
answer.replace(j, victim.length(), replacement);
return answer;
}

--
Cy
http://home.rochester.rr.com/cyhome/
Jul 22 '05 #5

P: n/a
On Tue, 10 Feb 2004 00:21:02 GMT, "Cy Edmunds"
<ce******@spamless.rochester.rr.com> wrote:
Let's say I have a std::string, and I want to replace all the ','
characters with " or ", i.e. "A,B,C" -> "A or B or C". Is the
following the best way to do it?

int idx;
while( (idx=str.find_first_of(',')) >= 0 ) {
str.replace( idx, 1, "" );
str.insert( idx, " or " );
}

(Stroustrup wasn't too illuminating here, unfortunately.)
std::string // replace all instances of victim with replacement
mass_replace(const std::string &source, const std::string &victim, const
std::string &replacement)
{
std::string answer = source;
std::string::size_type j = 0;
while ((j = answer.find(victim, j)) != std::string::npos )
answer.replace(j, victim.length(), replacement);
return answer;
}


This function doesn't work.

mass_replace("a", "a", "a");

Oops.

--
Be seeing you.
Jul 22 '05 #6

P: n/a
"Thore Karlsen" <si*@6581.com> wrote in message
news:qk********************************@4ax.com...
On Tue, 10 Feb 2004 00:21:02 GMT, "Cy Edmunds"
std::string // replace all instances of victim with replacement
mass_replace(const std::string &source, const std::string &victim, const
std::string &replacement)
{
std::string answer = source;
std::string::size_type j = 0;
while ((j = answer.find(victim, j)) != std::string::npos )
answer.replace(j, victim.length(), replacement);
return answer;
}


This function doesn't work.

mass_replace("a", "a", "a");

Oops.


Try mine, I spent a bit of time testing it for such corner cases
(since I needed to write something like that for myself anyway).

Of course I might have missed something... :-)

-Mike
Jul 22 '05 #7

P: n/a
On Tue, 10 Feb 2004 01:35:06 GMT, "Mike Wahler" <mk******@mkwahler.net>
wrote:
>std::string // replace all instances of victim with replacement
>mass_replace(const std::string &source, const std::string &victim, const
>std::string &replacement)
>{
> std::string answer = source;
> std::string::size_type j = 0;
> while ((j = answer.find(victim, j)) != std::string::npos )
> answer.replace(j, victim.length(), replacement);
> return answer;
>}
This function doesn't work.

mass_replace("a", "a", "a");

Oops.
Try mine, I spent a bit of time testing it for such corner cases
(since I needed to write something like that for myself anyway).


Thanks, but I already have my own, which I posted. :)

--
Be seeing you.
Jul 22 '05 #8

P: n/a

"Thore Karlsen" <si*@6581.com> wrote in message
news:di********************************@4ax.com...
On Tue, 10 Feb 2004 01:35:06 GMT, "Mike Wahler" <mk******@mkwahler.net>
wrote:
>std::string // replace all instances of victim with replacement
>mass_replace(const std::string &source, const std::string &victim, const >std::string &replacement)
>{
> std::string answer = source;
> std::string::size_type j = 0;
> while ((j = answer.find(victim, j)) != std::string::npos )
> answer.replace(j, victim.length(), replacement);
> return answer;
>} This function doesn't work.

mass_replace("a", "a", "a");

Oops.

Try mine, I spent a bit of time testing it for such corner cases
(since I needed to write something like that for myself anyway).


Thanks, but I already have my own, which I posted. :)


Sorry, I got the thread mixed up. I though I was replying to OP.

-Mike
Jul 22 '05 #9

P: n/a
Hi Mike.

"Mike Wahler" <mk******@mkwahler.net> wrote in message
news:ez*******************@newsread1.news.pas.eart hlink.net...
| "Thore Karlsen" <si*@6581.com> wrote in message
| news:qk********************************@4ax.com...
| > On Tue, 10 Feb 2004 00:21:02 GMT, "Cy Edmunds"
| >
| > >std::string // replace all instances of victim with replacement
| > >mass_replace(const std::string &source, const std::string &victim, const
| > >std::string &replacement)
| > >{
| > > std::string answer = source;
| > > std::string::size_type j = 0;
| > > while ((j = answer.find(victim, j)) != std::string::npos )
| > > answer.replace(j, victim.length(), replacement);
| > > return answer;
| > >}
| >
| > This function doesn't work.
| >
| > mass_replace("a", "a", "a");
| >
| > Oops.
|
| Try mine, I spent a bit of time testing it for such corner cases
| (since I needed to write something like that for myself anyway).
|
| Of course I might have missed something... :-)

Since you're interested in such an exercise for yourself,
then I thought the following might interest you too ;-):

# include <iostream>
# include <ostream>
# include <string>

inline std::string TrimBS( const std::string& S,
const std::string& Junk = " \a\b\f\t\n\r\v," )
{
const std::string::size_type First( S.find_first_not_of( Junk ) );
const std::string::size_type Last( S.find_last_not_of( Junk ) );

return ( First == std::string::npos ) ?
std::string( "" ) : S.substr( First, Last - First + 1 );
}

inline void ReplaceTokens( std::string& S, const std::string& Token )
{
S = TrimBS( S );
std::string::size_type Idx( 0 );
std::string::size_type Pos( 0 );
std::string::size_type Start( 0 );

static const char* GoodChars( "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" );

while( ( Pos = S.find_first_not_of( GoodChars, Start ) ) != std::string::npos )
{
if( ( Idx = S.find_first_of( GoodChars, Pos ) ) != std::string::npos )
{
S.erase( Pos, Idx - Pos );
S.insert( Pos, Token );
}

Start = Pos + Token.size();
}
}

int main()
{
std::string S( " A , B, C , D,Z, " );

std::cout << S << std::endl;
ReplaceTokens( S, " or " );
std::cout << S << std::endl;

return 0;
}

-- Input --
A , B, C , D,Z,

-- Output --
A or B or C or D or Z

Cheers.
Chris Val
Jul 22 '05 #10

P: n/a
Rolf Magnus <ra******@t-online.de> spoke thus:
Why do you first replace the ',' with an empty string and then insert
the " or " instead of just replacing it directly with " or "? str.replace(idx, 1, " or ");


Probably because I'm dumb (and Stroustrup doesn't go into specifics on
the std::string functions). Thanks.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Jul 22 '05 #11

P: n/a

"Chris ( Val )" <ch******@bigpond.com.au> wrote in message
news:c0*************@ID-110726.news.uni-berlin.de...
Hi Mike.

Since you're interested in such an exercise for yourself,
then I thought the following might interest you too ;-):


[snip misc string handling functions]

Thanks, Chris.

-Mike
Jul 22 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.