ke************@googlemail.com wrote:
hi all,
i'm trying to replace a string with known "tokens" with values -- and
am not sure how to do this effectively. Since i don't know the size
of the string containing the tokens to be replaced, i can't make a
buffer -- hence i thought of using malloc() -- is what i have below
effective? it doesn't seem to work though - the returned string just
returns the substituted part.
Any thoughts / comments are welcomed.
--------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *replaceString(unsigned char *orig, char *find, char *replace )
{
const char *p;
char *q, *to;
int i,d,match;
to = malloc( sizeof( char ) * strlen( find ) *
strlen( replace ) /
strlen( find ) );
It seems unlikely that this is what you meant. If the
numerator is not too large for a size_t, the argument is
just strlen(replace), a value that doesn't seem useful for
anything much. If the numerator *is* too big, the computed
value will be even less useful ...
Oh, and you forgot to check whether malloc() succeeded.
for( p = find, q = to; *p; p++ )
{
for( d = 0; d < strlen( find ); d++ )
{
if( *(p + d) == *(find + d) )
match = 1;
else
match = 0;
}
I don't see how this can be right, either. After `p' has
incremented one or more times from its initial value, `d' is
still happy to go all the way up to strlen(find) -- and that
means that `*(p+d)' can attempt to access bytes beyond the end
of the string ...
if( match )
{
for( i = 0; i < strlen( replace ); i++ )
{
*(q + i ) = *(replace + i);
}
q=q+i; p=p+d-1;
}
*q=*p;q++;
*q = '\0';
}
return to;
}
int main( int argc, char **argv )
{
unsigned char *str = "This is my string %n";
char f[] = "%n";
char r[] = "23";
unsigned char *replaced;
replaced = replaceString( str, f, r );
printf( "I see: %s\n", replaced );
return 0;
}
Since this has a homework-y flavor about it I won't offer
complete code. But here's an outline of how the code might be
written:
1) Scan through the original string once, just to count the
number of times the "find" string appears. The strstr()
function will be useful here; remember that after finding
an occurrence of "find" you should skip past the whole
thing before searching again. (Otherwise, a "find" string
like "##" would give an incorrect count on an input like
"My telephone number is ###-###-####.")
2) Knowing the length of the original string, the length of
the "find" string, the length of the replacement, and the
number of matches, you can now calculate how much space the
result string will need. Allocate that much space (don't
forget room for the terminating '\0'). If malloc() returns
NULL, just return NULL without proceeding further.
3) Now make a second pass through the string, looking for
occurrences of the "find" string. Copy everything before
the match to the result (starting from the beginning of
the original or from the end of the previous "find"), then
add a copy of the replacement string. The memcpy() function
will be useful here, because you're dealing with pieces of
strings that are not themselves strings.
4) Finally, copy the unmatched tail end of the original string
to the result, not forgetting to include the '\0'. The
strcpy() function will be useful here.
--
Er*********@sun.com