Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

help with string manipulation

Status
Not open for further replies.

Iceman2005

Programmer
May 6, 2005
22
US
Hi... i need help with simple strings.......
you guys should know it....

given a string..... like....

string ss = "blah blah blah ...";

Q: how do i replace ALL instance of a substr with another string? Like if i want to replace all the letter "a" to another letter or phrase.... how do i do that?

is there a function that can do it like....

ss.replace(from_first_char, to_last_char, "a", "new string");

thank you.
Imp

 
Replacing 1 char with another char is easy:
Code:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
	string test( "Blah, blah, blah..." );
	cout << test << endl;

	replace( test.begin(), test.end(), 'a', 'x' );
	cout << test << endl;

	return 0;
}
 
Combine the replace and find member functions in a loop.
Code:
#include <iostream>
#include <string>

int main()
{
    using namespace std;

    string ss = "blah blah blah ...";
    string searchStr = "a";
    string replaceStr = "new string";

    cout << ss << endl;

    size_t findPos;
    while ((findPos = ss.find(searchStr)) != string::npos)
        ss.replace(findPos, searchStr.size(), replaceStr);

    cout << ss << endl;
}
 
uolj

the sample you showed is ok.... but not perfect....
it did not handle for the case that....

string ss = "blah blah blah ...";
string searchStr = "a";
string replaceStr = "abc";

this went in an infinite loop because a replace with a replaced with more aaaaaaa'ssss

anyone can help?
 
What about this:
Code:
#pragma warning( disable: 4786 )
#include <cassert>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>

using namespace std;


bool
IsWhiteSpace( char c )
{
    return ( (c == ' ')  || (c == '\t') ||
             (c == '\r') || (c == '\n') );
}


void
Tokenize( vector<string>&  strings,
            const string&  fullString )
{
    string::size_type pos   = 0;
    string::size_type size  = fullString.size();
    string temp;

    // Skip whitespace at beginning.
    for ( ; pos < size; ++pos )
    {
        if ( IsWhiteSpace( fullString[ pos ] ) == true )
        {
            temp += fullString[ pos ];
        }
        else
        {
            break;
        }
    }

    if ( temp.size() > 0 )
    {
        strings.push_back( temp );
        temp.erase();
    }

    // Now put each word into the vector.
    string::size_type wordStart = pos;
    bool val = true;

    for ( ; pos < size; ++pos )
    {
        if ( IsWhiteSpace( fullString[ pos ] ) == val )
        {
            // Add the word or whitespace to the vector.
            strings.push_back( fullString.substr( wordStart, pos - wordStart ) );
            wordStart = pos;
            val = !val;
        }
    }

    if ( pos > wordStart )
    {
        strings.push_back( fullString.substr( wordStart, pos - wordStart ) );
    }
}


void
Replace(         string&  str,
        string::iterator  start,
        string::iterator  end,
                 string&  oldStr,
                 string&  newStr )
{
    string temp( start, end );
    vector<string> strings;
    Tokenize( strings, temp );

    temp.erase();
    unsigned int size = strings.size();

    for ( unsigned int index = 0; index < size; ++index )
    {
        if ( strings[ index ] == oldStr )
        {
            temp += newStr;
        }
        else
        {
            temp += strings[ index ];
        }
    }

    str.replace( start, end, temp );
}


int main()
{
    string test( "One and two and three" );
    cout << test << endl;

    string oldStr( "and" );
    string newStr( "or" );
    Replace( test, test.begin(), test.end(), oldStr, newStr );
    cout << test << endl;

    return 0;
}
 
Sorry. It's a pretty simple fix, just use the version of find that takes an offset, and use the previous find and the replaced value for the offset:
Code:
#include <iostream>
#include <string>

int main()
{
    using namespace std;

    string ss = "blah blah blah ...";
    string searchStr = "a";
    string replaceStr = "abc";

    cout << ss << endl;

    size_t findPos = 0;
    while ((findPos = ss.find(searchStr, findPos)) != string::npos)
    {
        ss.replace(findPos, searchStr.size(), replaceStr);
        findPos += replaceStr.size();
    }

    cout << ss << endl;
}
 
hi cpjust

thanks... but em.... i was more looking into the standard way of doing it.... like dont need to reinvent the wheel to do it right. Because the reason to try to code this from scratch and make it really work is kinda difficult.

your program is better than the other guy. it works in many cases... but still.... failed in some cases....
like this main here...

int main()
{
string test( "++ One + two + three ++" );
cout << test << endl;

string oldStr( "+" );
string newStr( "+++" );
Replace( test, test.begin(), test.end(), oldStr, newStr );
cout << test << endl;

return 0;
}


but thanks anyways man. i can probably use it. just not for every case.
 
Make sure you check my last post from 5 minutes before yours. It works better now (although you should be able to look up these functions and figure out a solution as well). It also works for your latest test with the +'s.

I don't know of any "standard" way of doing it, but it is quite possible that there is a more streamlined version that I just don't know about.

- the "other guy" ;-)
 
ahhhhh.... uolj

yes... that code of yours might work after all.
so far, it passwd all my test....

looks gooooood.

thanks buddy.
 
My version replaces only whole words.
Example: Replacing "and" with "or" does this:
"Sand and water don't mix" becomes "Sand or water don't mix"

The other way will do this:
"Sand and water don't mix" becomes "Sor or water don't mix"

So it just depends on what what you're trying to accomplish.
 
BTW thanks uolj, my code was pretty old so I updated it to a much smaller function:
Code:
void
Replace(  string&  str,
    const string&  searchStr,
    const string&  replaceStr )
{
    typedef string::size_type   size_type;
    size_type searchSize   = searchStr.size();
    size_type replaceSize  = replaceStr.size();
    size_type findPos      = 0;

    while ( (findPos = str.find( searchStr, findPos )) != string::npos )
    {
        if ( (IsWhiteSpace( str[ findPos - 1 ] ) == true) &&
             (IsWhiteSpace( str[ findPos + searchSize ] ) == true) )
        {
            str.replace( findPos, searchSize, replaceStr );
            findPos += replaceSize;
        }
        else
        {
            findPos += searchSize;
        }
    }
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top