strtok as string replace function problem ?

L

Lothar Behrens

Hi,

I have selected strtok to be used in my string replacement function.
But I lost the last token, if there is one.

This string would be replaced

select "name", "vorname", "userid", "passwort" from "users" order by
"users"

by this one:

select "name", "vorname", "userid",
"passwort" from "users" order by "users

Thus the last quot is lost.

Is there something missing in the code ?

Thanks, Lothar

lb_I_String& LB_STDCALL lbString::replace(const char* toReplace, const
char* with) {
// Don't worry about my object variables :)
UAP_REQUEST(getModuleInstance(), lb_I_String, rep)

// the string
char* token = strtok(stringdata, toReplace);

if ((token != NULL) && (token != stringdata)) {
*rep += with;
}

while(token != NULL)
{
*rep += token;
token = strtok(NULL, toReplace);
if (token != NULL) *rep += with;
}

setData(rep->charrep());

return *this;
}
 
D

Default User

Lothar said:
Hi,

I have selected strtok to be used in my string replacement function.
But I lost the last token, if there is one.

This string would be replaced

select "name", "vorname", "userid", "passwort" from "users" order by
"users"

by this one:

select "name", "vorname", "userid",
"passwort" from "users" order by "users

Thus the last quot is lost.

Is there something missing in the code ?


Scrap the entire thing. Use std::string and its replace() member
function.

Here's an example I have laying around, it could be lot more generic.


#include <string>
#include <iostream>


int main()
{
std::string test = "1231231231\n";
std::string rep = "one";

std::string::size_type curr = 0;
while ((curr = test.find("1", curr)) != std::string::npos)
{
test.replace(curr, 1, rep);
}

std::cout << test;

return 0;
}



Brian
 
L

Lothar Behrens

Scrap the entire thing. Use std::string and its replace() member
function.

In my past I had issues to avoid std::string. I do write multiplatform
code with Watcom - or
Open Watcom for now on Windows.

Therefore I tried to use strtok.

Lothar
 
T

Thomas J. Gritzan

Lothar said:
I have selected strtok to be used in my string replacement function.
But I lost the last token, if there is one.

This string would be replaced

select "name", "vorname", "userid", "passwort" from "users" order by
"users"

by this one:

select &quot;name&quot;, &quot;vorname&quot;, &quot;userid&quot;,
&quot;passwort&quot; from &quot;users&quot; order by &quot;users

Thus the last quot is lost.

Is there something missing in the code ?
lb_I_String& LB_STDCALL lbString::replace(const char* toReplace, const
char* with) { [...]
char* token = strtok(stringdata, toReplace);
[...]

You didn't lost a token, you lost a delimiter. The second argument to
strtok is a delimiter string, and the function gives you the tokens in
between. When there is a delimiter at the end, it is lost.

Try to write the function with strchr.

Or better try the much more easily to handle std::string. :)
 
G

Gavin Deane

In my past I had issues to avoid std::string. I do write multiplatform
code with Watcom - or
Open Watcom for now on Windows.

Therefore I tried to use strtok.

How far back in your past did you have issues with std:string? It is
no less standard than strtok and so should be perfectly suitable for
use in platform-independent code if it's the right tool for the job
(which it sounds like it might well be). I'd be surprised if any
modern C++ development tools had many issues with something as
fundamental as std::string.

If the problems you had were with a compiler developed several years
ago, you will probably find they've gone away with more up to date
compilers. If you had problems with a relatively modern compiler then,
unless it was something quite esoteric, I would think it a quality of
implementation issue of some concern.

Gavin Deane


Gavin Deane
 
B

BobR

Lothar Behrens said:
Hi,
I have selected strtok to be used in my string replacement function.
But I lost the last token, if there is one.
This string would be replaced

select "name", "vorname", "userid", "passwort" from "users" order by
"users"

by this one:

select &quot;name&quot;, &quot;vorname&quot;, &quot;userid&quot;,
&quot;passwort&quot; from &quot;users&quot; order by &quot;users

Thus the last quot is lost. Is there something missing in the code ?
Thanks, Lothar

lb_I_String& LB_STDCALL lbString::replace(const char* toReplace, const
char* with) {
// Don't worry about my object variables :)
UAP_REQUEST( getModuleInstance(), lb_I_String, rep )
// the string
char* token = strtok( stringdata, toReplace );
if( (token != NULL) && (token != stringdata) ) {
*rep += with;
}
while( token != NULL ){
*rep += token;
token = strtok( NULL, toReplace );
if( token != NULL ) *rep += with;
}
setData( rep->charrep() );
return *this;
}

Please read this before your next post:
http://www.parashift.com/c++-faq-lite/how-to-post.html

Here's a (loose) example that does what you want:

#include <iostream>
#include <string>

int main(){ using std::cout // for NG post
std::string RepTest("select \"name\", \"vorname\", \"userid\",
\"passwort\" from \"users\" order by \"users\"");
// the above should be all one line.
cout<<RepTest<<std::endl;
std::string Sfind( "\"" );
std::string Sput( "&quot;" );
size_t pos;
while( ( pos = RepTest.find( Sfind ) ) != RepTest.npos ){
RepTest.erase(pos, 1);
RepTest.insert(pos, Sput);
}
cout<<RepTest<<std::endl;

return 0;
} // main()

/* - output -
select "name", "vorname", "userid", "passwort" from "users" order by "users"
select &quot;name&quot;, &quot;vorname&quot;, &quot;userid&quot;,
&quot;passwort&quot; from &quot;users&quot; order by &quot;users&quot;
*/

Should be simple to build a function from that.
(gotta leave something for you to do. <G>).
 
L

Lothar Behrens


Thank you all.

I'll take a look at std::string by searching in the samples of Open
Watcom for it.

BTW. I have fixed the problem if I have understood the strtok function
correctly.

Can the token be a 'multi character' string such as "\\\"" ?

(Not tokenizing '\\' and \"')

Maybe this would be a problem in my replace implementation.

Regards, Lothar
 
D

Default User

Lothar Behrens wrote:
BTW. I have fixed the problem if I have understood the strtok function
correctly.

Can the token be a 'multi character' string such as "\\\"" ?

No. It can easily be done with some small modifications to the code I
gave you earlier.




Brian
 
B

BobR

Lothar Behrens said:
Thank you all.

I'll take a look at std::string by searching in the samples of Open
Watcom for it.

Why not just try my (and/or Default User's) example. If it compiles, you're
BTW. I have fixed the problem if I have understood the strtok function
correctly.
Can the token be a 'multi character' string such as "\\\"" ?
(Not tokenizing '\\' and \"')

Do you mean the 'delimiter'? Here is an example right out of the GNU 'libC'
docs:
// note this is 'C' code.
// for 'C++', change the name 'string' to something else.

const char string[] = "words separated by spaces -- and, punctuation!";
const char delimiters[] = " .,;:!-";
char *token, *cp;
...
cp = strdupa (string); /* Make writable copy. */
token = strtok (cp, delimiters); /* token => "words" */
token = strtok (NULL, delimiters); /* token => "separated" */
token = strtok (NULL, delimiters); /* token => "by" */
token = strtok (NULL, delimiters); /* token => "spaces" */
token = strtok (NULL, delimiters); /* token => "and" */
token = strtok (NULL, delimiters); /* token => "punctuation" */
token = strtok (NULL, delimiters); /* token => NULL */

I've never used 'strtok'. I "git 'er done" with std::string and
std::stringstream.
So, if the above does not answer your question, you'll have to repost and
wait for an expert with his/her roots in 'C' (or 'strtok' experience).
If you were asking about the escape char (\), I don't know how 'strtok'
handles it. Experiment.

If you are going to code in 'C++', you really should learn std::string at a
minimum.
 
T

Thomas J. Gritzan

BobR said:
Do you mean the 'delimiter'? Here is an example right out of the GNU 'libC'
docs:
// note this is 'C' code.
// for 'C++', change the name 'string' to something else.

Why? string is not a keyword.
const char string[] = "words separated by spaces -- and, punctuation!";
const char delimiters[] = " .,;:!-"; [...]
So, if the above does not answer your question, you'll have to repost and
wait for an expert with his/her roots in 'C' (or 'strtok' experience).
If you were asking about the escape char (\), I don't know how 'strtok'
handles it. Experiment.

strtok doesn't handle escape characters.
If you are going to code in 'C++', you really should learn std::string at a
minimum.

*sign*
 
T

Thomas J. Gritzan

Lothar said:
Thank you all.

I'll take a look at std::string by searching in the samples of Open
Watcom for it.

BTW. I have fixed the problem if I have understood the strtok function
correctly.

Can the token be a 'multi character' string such as "\\\"" ?

(Not tokenizing '\\' and \"')

Maybe this would be a problem in my replace implementation.

Yes. strtok handles the delimiter string as collection of single chars. If
you want to replace substrings by strings, you would have to write another
implementation, perhaps searching the toReplace string with strstr and
replacing it.

Perhaps you get better answers in comp.lang.c for questions about the C
standard library (the people there are used to it).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top