I'm looking for a way to replace word/words in string. let's say if i use function like this:
changewords("Hello I'm Number One","Number One","Zero");
the output will be like: "Hello I'm Number One" -> "Hello I'm Zero"
but more of then i will able to replace only one word too
changewords("Hello I'm Number One","One","Four");
like this: "Hello I'm Number One" -> "Hello I'm Number Four"
In my code i split sentence to words and the compare each word to the word that i need to change, but i able to change only one word in that way, any one can advice how to do it correctly please? Thanks. Here is my code, it using one line from matrix (table) as a sentence, and the line number is the sentenceToChange variable.
int changewords (char table[][MAX_SENTENCE_LENGTH], int numOfSentences, int sentenceToChange, char subString[],char replaceWith[]){
int slen,i=0,q=0,c=0;
char wordlist[100][100];
char final[1][100];
slen=strlen(table[sentenceToChange]);
for(i=0;i<slen;i++) {
if(table[sentenceToChange][i]!=' '){
wordlist[q][c]=table[sentenceToChange][i];
c++;
}
else {
wordlist[q][c]='\0';
c=0;
q++;
}
}
for(i=0;i<q;i++) {
if (!strcmp(wordlist[i],subString)) {
strcpy(wordlist[i],replaceWith);
}
}
final[0][0]='\0';
for(i=0;i<=q;i++) {
strcat(final[0],wordlist[i]);
if(i!=q) strcat(final[0]," ");
}
final[0][slen-1]='\0';
strcpy(table[sentenceToChange],final[0]);
}
There are a couple of different strategies possible, which all can be tailored further if necessary.
find
and inserting replace
when found, the original character when not found;find
and inserting replace
when found, the original text when not found -- you will need this to replace entire words, rather than the literal find
text only;find
text.Which strategy to use depends on further (unmentioned) requirements, such as
find
or replace
begin and/or end with spaces, and are these significant?One of the harder things is to assess the necessary memory needed for the new string. Below, I assume there is always one string found and replaced. To cater for 'any' new string length, without pre-scanning find
and change
, a safer bet is to assume every single character in sentence
potentially can be replaced with replace
; that is, the maximum amount of memory the destination would take up is strlen(sentence)*strlen(replace)+1
(the +1, as always, is to store the terminating zero in).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *changewords_1 (char *sentence, char *find, char *replace)
{
char *dest = malloc (strlen(sentence)-strlen(find)+strlen(replace)+1);
char *destptr = dest;
*dest = 0;
while (*sentence)
{
if (!strncmp (sentence, find, strlen(find)))
{
strcat (destptr, replace);
sentence += strlen(find);
destptr += strlen(replace);
} else
{
*destptr = *sentence;
destptr++;
sentence++;
}
}
*destptr = 0;
return dest;
}
char *changewords_2 (char *sentence, char *find, char *replace)
{
char *dest = malloc (strlen(sentence)-strlen(find)+strlen(replace)+1);
char *destptr = dest;
*dest = 0;
while (*sentence)
{
if (!strncmp (sentence, find, strlen(find)) &&
(sentence[strlen(find)] == 0 || sentence[strlen(find)] == ' '))
{
strcat (destptr, replace);
sentence += strlen(find);
destptr += strlen(replace);
} else
{
while (*sentence && *sentence != ' ')
{
*destptr = *sentence;
destptr++;
sentence++;
}
while (*sentence == ' ')
{
*destptr = *sentence;
destptr++;
sentence++;
}
}
}
*destptr = 0;
return dest;
}
char *changewords_3 (char *sentence, char *find, char *replace)
{
char *dest = malloc (strlen(sentence)-strlen(find)+strlen(replace)+1);
char *ptr;
strcpy (dest, sentence);
ptr = strstr (dest, find);
if (ptr)
{
memmove (ptr+strlen(replace), ptr+strlen(find), strlen(ptr+strlen(find))+1);
strncpy (ptr, replace, strlen(replace));
}
return dest;
}
int main (void)
{
char *result;
result = changewords_1 ("Hello I'm Number One","Number","Index");
printf ("[%s]\n", result);
free (result);
result = changewords_2 ("Here Is The Onerous Number One ...","One","Four");
printf ("[%s]\n", result);
free (result);
result = changewords_3 ("Here Is Number One Again","One","Fourty-Five Hundred");
printf ("[%s]\n", result);
free (result);
return 0;
}
.. which shows the output:
[Hello I'm Index One]
[Here Is The Onerous Number Four ...]
[Here Is Number Fourty-Five Hundred Again]
What is mentioned above about strstr would work. In fact there is an example here http://www.cplusplus.com/reference/cstring/strstr/
If you could not use strstr for some reason you could do the following.
1) Search through the first string, character by character looking for the first character of the words you wish to replace. When found, save the index of that location.
2) After finding the first character, continue verifying each character is a match, if not, go back to step 1.
3) When you have reached the end of the string you wish to replace, save the index of that location.
4) Save the remaining characters of the string you are conducting the substitution into a temporary string.
5) Copy the replace characters to the index found in step 1.
6) COpy the saved characters from the temporary string to the position indicated by the index from step 1 plus the length of the replacement characters.
Whatever method you use, there are some very important things to remember.
1) Make sure the memory allocated for the new string is sufficient to hold the replacement string since it is possible that the replacement is longer than the original.
2) Put the null character at the end of the new string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With