Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Search and replace algorithm for string

Reply
Thread Tools

Search and replace algorithm for string

 
 
M
Guest
Posts: n/a
 
      08-01-2005
Hi,

I've searched through the previous posts and there seems to be a few
examples of search and replacing all occurrances of a string with
another string.

I would have thought that the code below would work...

string gsub(const string & sData,
const string & sFrom,
const string & sTo)
{
string sNew = sData;

if (! sNew.empty())
{
std::replace(sData.begin(), sData.end(),
sFrom,
sTo);

}
return sNew;
}

But, it produces the following compiler error:

/usr/include/c++/3.2/bits/stl_algo.h: In function `void
std::replace(_ForwardIter, _ForwardIter, const _Tp&, const _Tp&) [with
_ForwardIter = __gnu_cxx::__normal_iterator<const char*,
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
>, _Tp = std::basic_string<char, std::char_traits<char>,
>std::allocator<char> >]':

str_tst.cpp:132: instantiated from here
/usr/include/c++/3.2/bits/stl_algo.h:809: no match for `const char& ==
const std::basic_string<char, std::char_traits<char>,
std::allocator<char> >&' operator
str_tst.cpp:132: instantiated from here
/usr/include/c++/3.2/bits/stl_algo.h:810: assignment of read-only
location
/usr/include/c++/3.2/bits/stl_algo.h:810: cannot convert `const
std::basic_string<char, std::char_traits<char>, std::allocator<char> >'
to `const char' in assignment

What am I doing wrong here? Looking at the function signature, it should
work. Cannot see why the attempted conversion.

Regards,

Michael
 
Reply With Quote
 
 
 
 
Andrew Koenig
Guest
Posts: n/a
 
      08-02-2005
"M" <(E-Mail Removed)> wrote in message
news:TDyHe.69154$(E-Mail Removed)...

> I would have thought that the code below would work...
>
> string gsub(const string & sData,
> const string & sFrom,
> const string & sTo)
> {
> string sNew = sData;
>
> if (! sNew.empty())
> {
> std::replace(sData.begin(), sData.end(),
> sFrom,
> sTo);
>
> }
> return sNew;
> }


Not unless you change the call to std::replace to use sNew instead of sData.


 
Reply With Quote
 
 
 
 
michaelkatsilis@yahoo.com
Guest
Posts: n/a
 
      08-02-2005

Andrew Koenig wrote:
> "M" <(E-Mail Removed)> wrote in message
> news:TDyHe.69154$(E-Mail Removed)...

<SNIP>
> Not unless you change the call to std::replace to use sNew instead of sData.


Hi Andrew,

No go, I still the same problem (sorry about the above though, just
changed some of the variable names).

Here is the test code:

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

using namespace std;

string gsub(const string & sData,
const string & sFrom,
const string & sTo)
{
string sNew = sData;
if (! sNew.empty())
{
std::replace(sNew.begin(), sNew.end(),
sFrom,
sTo);
}
return sNew;
}


int main(void)
{
const string sData = "Some text";
string sFrom = "text";
string sTo = "information";

cout << "Original text: "
<< sData
<< "\n"
<< "After search and replace: "
<< gsub(sData, sFrom, sTo)
<< endl;

return 0;
}


The above compiler error was produced on linux, the following error on
aix

"/usr/.../include/algorithm", line 243.25: 1540-0218 (S) The call does
not match any parameter list for "operator==".
"/usr/.../include/utility", line 77.14: 1540-1283 (I) "template <class
_T1, class _T2> std:perator==(const pair<_T1,_T2> &, const
pair<_T1,_T2> &)" is not a viable candidate.
"/usr/.../include/xutility", line 384.14: 1540-1283 (I) "template
<class _RI> std:perator==(const reverse_iterator<_RI> &, const
reverse_iterator<_RI> &)" is not a viable candidate.
"/usr/.../include/xutility", line 499.14: 1540-1283 (I) "template
<class _E, class _Tr> std:perator==(const istreambuf_iterator<_E,_Tr>
&, const istreambuf_iterator<_E,_Tr> &)" is not a viable candidate.
"/usr/.../include/xmemory", line 155.14: 1540-1283 (I) "template <class
_Ty, class _U> std:perator==(const allocator<_Ty> &, const
allocator<_U> &)" is not a viable candidate.
"/usr/.../include/string", line 101.14: 1540-1283 (I) "template <class
_E, class _Tr, class _A> std:perator==(const basic_string<_E,_Tr,_A>
&, const basic_string<_E,_Tr,_A> &)" is not a viable candidate.
"/usr/.../include/string", line 105.14: 1540-1283 (I) "template <class
_E, class _Tr, class _A> std:perator==(const _E *, const
basic_string<_E,_Tr,_A> &)" is not a viable candidate.
"/usr/.../include/string", line 109.14: 1540-1283 (I) "template <class
_E, class _Tr, class _A> std:perator==(const basic_string<_E,_Tr,_A>
&, const _E *)" is not a viable candidate.
"/usr/.../include/iterator", line 184.14: 1540-1283 (I) "template
<class _Ty, class _E, class _Tr, class _Dist> std:perator==(const
istream_iterator<_Ty,_E,_Tr,_Dist> &, const
istream_iterator<_Ty,_E,_Tr,_Dist> &)" is not a viable candidate.
"/usr/.../include/algorithm", line 241.14: 1540-0700 (I) The previous
message was produced while processing
"std::replace<std::_Ptrit<char,long,char *,char &,char *,char
&>,std::basic_string<char,std::char_traits<char>,s td::allocator<char> >
>(_Ptrit<char,long,char *,char &,char *,char &>, _Ptrit<char,long,char *,char &,char *,char &>, const basic_string<char,std::char_traits<char>,std::allo cator<char> > &, const basic_string<char,std::char_traits<char>,std::allo cator<char> > &)".

"strtst.cpp", line 19.9: 1540-0700 (I) The previous message was
produced while processing "gsub(const string &, const string &, const
string &)".
"/usr/.../include/algorithm", line 244.29: 1540-0218 (S) The call does
not match any parameter list for "operator=".
"/usr/.../include/algorithm", line 244.29: 1540-1283 (I) "builtin
operator=(char, char)" is not a viable candidate.

Regards,

Michael

 
Reply With Quote
 
Larry I Smith
Guest
Posts: n/a
 
      08-02-2005
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> Andrew Koenig wrote:
>>"M" <(E-Mail Removed)> wrote in message
>>news:TDyHe.69154$(E-Mail Removed)...

> <SNIP>
>>Not unless you change the call to std::replace to use sNew instead of sData.

>
> Hi Andrew,
>
> No go, I still the same problem (sorry about the above though, just
> changed some of the variable names).
>
> Here is the test code:
>
> #include <iostream>
> #include <algorithm>
> #include <string>
>
> using namespace std;
>
> string gsub(const string & sData,
> const string & sFrom,
> const string & sTo)
> {
> string sNew = sData;
> if (! sNew.empty())
> {
> std::replace(sNew.begin(), sNew.end(),
> sFrom,
> sTo);
> }
> return sNew;
> }
>
>
> int main(void)
> {
> const string sData = "Some text";
> string sFrom = "text";
> string sTo = "information";
>
> cout << "Original text: "
> << sData
> << "\n"
> << "After search and replace: "
> << gsub(sData, sFrom, sTo)
> << endl;
>
> return 0;
> }
>
>
> The above compiler error was produced on linux, the following error on
> aix
>
> "/usr/.../include/algorithm", line 243.25: 1540-0218 (S) The call does
> not match any parameter list for "operator==".
> "/usr/.../include/utility", line 77.14: 1540-1283 (I) "template <class
> _T1, class _T2> std:perator==(const pair<_T1,_T2> &, const
> pair<_T1,_T2> &)" is not a viable candidate.
> "/usr/.../include/xutility", line 384.14: 1540-1283 (I) "template
> <class _RI> std:perator==(const reverse_iterator<_RI> &, const
> reverse_iterator<_RI> &)" is not a viable candidate.
> "/usr/.../include/xutility", line 499.14: 1540-1283 (I) "template
> <class _E, class _Tr> std:perator==(const istreambuf_iterator<_E,_Tr>
> &, const istreambuf_iterator<_E,_Tr> &)" is not a viable candidate.
> "/usr/.../include/xmemory", line 155.14: 1540-1283 (I) "template <class
> _Ty, class _U> std:perator==(const allocator<_Ty> &, const
> allocator<_U> &)" is not a viable candidate.
> "/usr/.../include/string", line 101.14: 1540-1283 (I) "template <class
> _E, class _Tr, class _A> std:perator==(const basic_string<_E,_Tr,_A>
> &, const basic_string<_E,_Tr,_A> &)" is not a viable candidate.
> "/usr/.../include/string", line 105.14: 1540-1283 (I) "template <class
> _E, class _Tr, class _A> std:perator==(const _E *, const
> basic_string<_E,_Tr,_A> &)" is not a viable candidate.
> "/usr/.../include/string", line 109.14: 1540-1283 (I) "template <class
> _E, class _Tr, class _A> std:perator==(const basic_string<_E,_Tr,_A>
> &, const _E *)" is not a viable candidate.
> "/usr/.../include/iterator", line 184.14: 1540-1283 (I) "template
> <class _Ty, class _E, class _Tr, class _Dist> std:perator==(const
> istream_iterator<_Ty,_E,_Tr,_Dist> &, const
> istream_iterator<_Ty,_E,_Tr,_Dist> &)" is not a viable candidate.
> "/usr/.../include/algorithm", line 241.14: 1540-0700 (I) The previous
> message was produced while processing
> "std::replace<std::_Ptrit<char,long,char *,char &,char *,char
> &>,std::basic_string<char,std::char_traits<char>,s td::allocator<char> >
>>(_Ptrit<char,long,char *,char &,char *,char &>, _Ptrit<char,long,char *,char &,char *,char &>, const basic_string<char,std::char_traits<char>,std::allo cator<char> > &, const basic_string<char,std::char_traits<char>,std::allo cator<char> > &)".

> "strtst.cpp", line 19.9: 1540-0700 (I) The previous message was
> produced while processing "gsub(const string &, const string &, const
> string &)".
> "/usr/.../include/algorithm", line 244.29: 1540-0218 (S) The call does
> not match any parameter list for "operator=".
> "/usr/.../include/algorithm", line 244.29: 1540-1283 (I) "builtin
> operator=(char, char)" is not a viable candidate.
>
> Regards,
>
> Michael
>


If I'm not mistaken, replace will replace all occurences of a char
with another char (e.g. change all 'a' to 'b'), but does not replace
multi-char substrings.

Larry
 
Reply With Quote
 
Kelly Walker
Guest
Posts: n/a
 
      08-02-2005
"M" <(E-Mail Removed)> wrote in message
news:TDyHe.69154$(E-Mail Removed)...
> Hi,
>
> I've searched through the previous posts and there seems to be a few
> examples of search and replacing all occurrances of a string with
> another string.
>
> I would have thought that the code below would work...
>
> string gsub(const string & sData,
> const string & sFrom,
> const string & sTo)
> {
> string sNew = sData;
>
> if (! sNew.empty())
> {
> std::replace(sData.begin(), sData.end(),
> sFrom,
> sTo);
>
> }
> return sNew;
> }
>


This is not the main issue, but you cannot call replace on sData because it
is const. I am sure you mean sNew. Why not pass the string by value in the
first place:

string gsub(string sNew,
const string & sFrom,
const string & sTo) { ... }

You gain nothing by passing it be reference if you just copy it.

> What am I doing wrong here? Looking at the function signature, it should
> work. Cannot see why the attempted conversion.
>
> Regards,
>
> Michael


The problem is that std::string's iterators refer to individual characters
in the string, NOT substrings. So, you cannot replace a substring with
another string using iterators and std::replace. You can replace characters
as in:

std::string str("aaaaa");
std::replace(str.begin(), str.end(), 'a', 'b');
// str is now "bbbbb"

If you want to replace substrings, you will have to do something more
complicated like:

string gsub(const string &sData,
const string &sFrom,
const string &sTo) {

string sNew;
size_t i = 0;
while(i < sData.size()) {
if(sData.substr(i, sFrom.size()) == sFrom) {
sNew += sTo;
i += sFrom.size();
}
else {
sNew += sData[i];
++i;
}
}
return sNew;
}

This is probably not the most efficient way to do what you want, but you get
the idea.

-Kelly


 
Reply With Quote
 
michaelkatsilis@yahoo.com
Guest
Posts: n/a
 
      08-02-2005
Hi Larry,

It looks like your correct, looking at the error message. But when
looking at the function signature

void replace(_FI _F, _FI _L, const _Ty& _Vo, const _Ty& _Vn) { ... }

it's easy to mistake as _Ty is misleading (should have probably been _E
or something else). The code for the above version of replace, iterates
over each element and replaces it with the new if it encounters the
old.

If this is correct, then I'll apply one of the solutions I've found
during the search I made on this group. Thanks for your help.

Regards,

Michael

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      08-02-2005
(E-Mail Removed) wrote:
> Andrew Koenig wrote:
>> "M" <(E-Mail Removed)> wrote in message
>> news:TDyHe.69154$(E-Mail Removed)...

> <SNIP>
>> Not unless you change the call to std::replace to use sNew instead
>> of sData.

>
> Hi Andrew,
>
> No go, I still the same problem (sorry about the above though, just
> changed some of the variable names).
> [..]


I think Andrew is mistaken (as is Michael). std::replace cannot be used
to replace a substring within a string with another substring. You need
to use 'std::string::replace' (a member function) for that. RTFM please.

V


 
Reply With Quote
 
Larry I Smith
Guest
Posts: n/a
 
      08-02-2005
(E-Mail Removed) wrote:
> Hi Larry,
>
> It looks like your correct, looking at the error message. But when
> looking at the function signature
>
> void replace(_FI _F, _FI _L, const _Ty& _Vo, const _Ty& _Vn) { ... }
>
> it's easy to mistake as _Ty is misleading (should have probably been _E
> or something else). The code for the above version of replace, iterates
> over each element and replaces it with the new if it encounters the
> old.
>
> If this is correct, then I'll apply one of the solutions I've found
> during the search I made on this group. Thanks for your help.
>
> Regards,
>
> Michael
>


Here's one possible solution:

string gsub(const string& sData,
const string& sFrom,
const string& sTo)
{
string sNew = sData;

if (! sNew.empty())
{
string::size_type loc;

while (string::npos != (loc = sNew.find(sFrom)))
sNew.replace(loc, sFrom.length(), sTo);
}

return sNew;
}

Regards,
Larry
 
Reply With Quote
 
michaelkatsilis@yahoo.com
Guest
Posts: n/a
 
      08-02-2005
Victor,

string::replace won't do it either, so you RTFM please.

Regards,

Michael

 
Reply With Quote
 
Kelly Walker
Guest
Posts: n/a
 
      08-02-2005
"Kelly Walker" <(E-Mail Removed)> wrote in message
news:64BHe.1725$(E-Mail Removed) k.net...
> "M" <(E-Mail Removed)> wrote in message
> news:TDyHe.69154$(E-Mail Removed)...
>> Hi,
>>
>> I've searched through the previous posts and there seems to be a few
>> examples of search and replacing all occurrances of a string with
>> another string.
>>
>> I would have thought that the code below would work...
>>
>> string gsub(const string & sData,
>> const string & sFrom,
>> const string & sTo)
>> {
>> string sNew = sData;
>>
>> if (! sNew.empty())
>> {
>> std::replace(sData.begin(), sData.end(),
>> sFrom,
>> sTo);
>>
>> }
>> return sNew;
>> }
>>

>
> This is not the main issue, but you cannot call replace on sData because
> it is const. I am sure you mean sNew. Why not pass the string by value
> in the first place:
>
> string gsub(string sNew,
> const string & sFrom,
> const string & sTo) { ... }
>
> You gain nothing by passing it be reference if you just copy it.
>
>> What am I doing wrong here? Looking at the function signature, it should
>> work. Cannot see why the attempted conversion.
>>
>> Regards,
>>
>> Michael

>
> The problem is that std::string's iterators refer to individual characters
> in the string, NOT substrings. So, you cannot replace a substring with
> another string using iterators and std::replace. You can replace
> characters as in:
>
> std::string str("aaaaa");
> std::replace(str.begin(), str.end(), 'a', 'b');
> // str is now "bbbbb"
>
> If you want to replace substrings, you will have to do something more
> complicated like:
>
> string gsub(const string &sData,
> const string &sFrom,
> const string &sTo) {
>
> string sNew;
> size_t i = 0;
> while(i < sData.size()) {
> if(sData.substr(i, sFrom.size()) == sFrom) {
> sNew += sTo;
> i += sFrom.size();
> }
> else {
> sNew += sData[i];
> ++i;
> }
> }
> return sNew;
> }
>
> This is probably not the most efficient way to do what you want, but you
> get the idea.
>
> -Kelly
>


Oops - I forgot about string::replace()...


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
automated sub-string search/replace algorithm... Chris M. Thomasson C Programming 40 03-26-2010 11:34 AM
Replace /n with a XHTML <br /> using string.replace Alun ASP .Net 3 02-18-2008 05:52 AM
how to make replace function replace globally in a string V S Rawat Javascript 5 07-03-2007 08:02 PM
help with string replace - for doing selective replace Prasad S Javascript 2 08-27-2004 03:22 PM
Key generation algorithm and Cipher algorithm Ahmed Moustafa Java 0 11-15-2003 06:35 AM



Advertisments