472,373 Members | 1,965 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,373 software developers and data experts.

Search and replace algorithm for string

M
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
Aug 2 '05 #1
13 10822
"M" <wh*@somewhere.com> wrote in message
news:TD******************@news-server.bigpond.net.au...
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.
Aug 2 '05 #2

Andrew Koenig wrote:
"M" <wh*@somewhere.com> wrote in message
news:TD******************@news-server.bigpond.net.au... <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::operator==(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::operator==(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::operator==(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::operator==(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::operator==(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::operator==(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::operator==(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::operator==(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

Aug 2 '05 #3
mi*************@yahoo.com wrote:
Andrew Koenig wrote:
"M" <wh*@somewhere.com> wrote in message
news:TD******************@news-server.bigpond.net.au...

<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::operator==(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::operator==(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::operator==(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::operator==(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::operator==(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::operator==(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::operator==(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::operator==(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
Aug 2 '05 #4
"M" <wh*@somewhere.com> wrote in message
news:TD******************@news-server.bigpond.net.au...
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
Aug 2 '05 #5
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

Aug 2 '05 #6
mi*************@yahoo.com wrote:
Andrew Koenig wrote:
"M" <wh*@somewhere.com> wrote in message
news:TD******************@news-server.bigpond.net.au...

<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
Aug 2 '05 #7
mi*************@yahoo.com 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
Aug 2 '05 #8
Victor,

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

Regards,

Michael

Aug 2 '05 #9
"Kelly Walker" <ke************@earthlink.net> wrote in message
news:64***************@newsread1.news.atl.earthlin k.net...
"M" <wh*@somewhere.com> wrote in message
news:TD******************@news-server.bigpond.net.au...
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()...
Aug 2 '05 #10
Victor,

Relax man, no need to get in a state about something so trivial.
std::string::replace won't do it either. Maybe take your own advise...

Regards,

Michael

Aug 2 '05 #11
Larry I Smith wrote:
mi*************@yahoo.com 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

This one excludes the previouslu scanned text from subsequent
replacements, in case the 'sTo' text itself (e.g. "Larry Smith")
includes text that matches 'sFrom' (e.g. "Smith").

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

if (! sNew.empty())
{
string::size_type toLen = sTo.length();
string::size_type frLen = sFrom.length();
string::size_type loc = 0;

while (string::npos != (loc = sNew.find(sFrom, loc)))
{
sNew.replace(loc, frLen, sTo);
loc += toLen;

if (loc >= sNew.length())
break;
}
}

return sNew;
}

Regards,
Larry
Aug 2 '05 #12
Hi Larry,

Thanks for the solution, I appreciate it.

Regards,

Michael

Aug 2 '05 #13
std::string really sucks.
no replaceAll, no EndWIth(), no StartWith(), no TrimXX, no auto
conversion to const char*, etc.
if you use more than 10 thousands of string in your app, it will take
more than 100M memory!

Aug 2 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: vic | last post by:
My manager wants me to develop a search program, that would work like they have it at edorado.com. She made up her requirements after having compared how search works at different websites, like...
10
by: pembed2003 | last post by:
Hi all, I asked this question in the C group but no one seems to be interested in answering it. :-( Basically, I wrote a search and replace function so I can do: char source = "abcd?1234?x";...
22
by: Phlip | last post by:
C++ers: Here's an open ended STL question. What's the smarmiest most templated way to use <string>, <algorithms> etc. to turn this: " able search baker search charlie " into this: " able...
4
by: Ben Fidge | last post by:
Hi What is the most efficient way to gather a list of files under a given folder recursively with the ability to specify exclusion file masks? For example, say I wanted to get a list of all...
60
by: Julie | last post by:
What is the *fastest* way in .NET to search large on-disk text files (100+ MB) for a given string. The files are unindexed and unsorted, and for the purposes of my immediate requirements, can't...
32
by: tshad | last post by:
Can you do a search for more that one string in another string? Something like: someString.IndexOf("something1","something2","something3",0) or would you have to do something like: if...
4
by: Dameon | last post by:
Hi All, I have a process where I'd like to search the contents of a file(in a dir) for all occurences (or the count of) of a given string. My goal is to focus more on performance, as some of the...
3
by: Vincent SHAO | last post by:
Search engine have to record all of the query string. Now i have a search engine log which contains 10 milllion query strings, but almost of them are repeated, not more than 3 million of them are...
14
by: S | last post by:
Any idea on how I would be able to do a search within C# that does ranges or words For example I want to search for Chicken in the string string s1 = "This is Great Chicken";
2
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
1
by: Matthew3360 | last post by:
Hi, I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web server and have made sure to enable curl. I get a...
0
Oralloy
by: Oralloy | last post by:
Hello Folks, I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA. My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
0
by: Rahul1995seven | last post by:
Introduction: In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python has gained popularity among beginners and experts...
1
by: Johno34 | last post by:
I have this click event on my form. It speaks to a Datasheet Subform Private Sub Command260_Click() Dim r As DAO.Recordset Set r = Form_frmABCD.Form.RecordsetClone r.MoveFirst Do If...
1
by: ezappsrUS | last post by:
Hi, I wonder if someone knows where I am going wrong below. I have a continuous form and two labels where only one would be visible depending on the checkbox being checked or not. Below is the...
0
by: jack2019x | last post by:
hello, Is there code or static lib for hook swapchain present? I wanna hook dxgi swapchain present for dx11 and dx9.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.