Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Quick std::string question

1 view
Skip to first unread message

Christopher Benson-Manica

unread,
Feb 9, 2004, 4:18:47 PM2/9/04
to
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.

Thore Karlsen

unread,
Feb 9, 2004, 4:25:44 PM2/9/04
to
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.

Rolf Magnus

unread,
Feb 9, 2004, 6:29:26 PM2/9/04
to
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?

Mike Wahler

unread,
Feb 9, 2004, 7:16:24 PM2/9/04
to
"Christopher Benson-Manica" <at...@nospam.cyberspace.org> wrote in message
news:c08tfn$rik$1...@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

Cy Edmunds

unread,
Feb 9, 2004, 7:21:02 PM2/9/04
to
"Christopher Benson-Manica" <at...@nospam.cyberspace.org> wrote in message
news:c08tfn$rik$1...@chessie.cirr.com...

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/


Thore Karlsen

unread,
Feb 9, 2004, 7:53:46 PM2/9/04
to
On Tue, 10 Feb 2004 00:21:02 GMT, "Cy Edmunds"
<cedm...@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.

Mike Wahler

unread,
Feb 9, 2004, 8:35:06 PM2/9/04
to
"Thore Karlsen" <s...@6581.com> wrote in message
news:qkag20th8uiofmiqd...@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


Thore Karlsen

unread,
Feb 9, 2004, 8:41:37 PM2/9/04
to
On Tue, 10 Feb 2004 01:35:06 GMT, "Mike Wahler" <mkwa...@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.

Mike Wahler

unread,
Feb 9, 2004, 9:03:15 PM2/9/04
to

"Thore Karlsen" <s...@6581.com> wrote in message
news:didg2093kfal2hsmk...@4ax.com...

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

-Mike


Chris ( Val )

unread,
Feb 10, 2004, 9:53:20 AM2/10/04
to
Hi Mike.

"Mike Wahler" <mkwa...@mkwahler.net> wrote in message
news:ezWVb.21823$uM2....@newsread1.news.pas.earthlink.net...

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


Christopher Benson-Manica

unread,
Feb 10, 2004, 12:33:35 PM2/10/04
to
Rolf Magnus <rama...@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.

Mike Wahler

unread,
Feb 10, 2004, 3:00:57 PM2/10/04
to

"Chris ( Val )" <chri...@bigpond.com.au> wrote in message
news:c0ar93$13e4np$1...@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


0 new messages