4

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]);

}

Matan
  • 81
  • 1
  • 1
  • 6
  • 2
    You're making it way too complicated - just use `strstr` to find the target string, then a couple of calls to `memmove` to insert the new string and adjust the remaining part. – Paul R Nov 26 '14 at 22:46
  • 1
    Adding to the above... after you find a match with `strstr()` you may also want to check that the chars right before and after are not alpha/alphanumeric, in case you matched part of a longer word. – Dmitri Nov 26 '14 at 23:15
  • Thanks for your advices and helping. – Matan Nov 27 '14 at 17:54

4 Answers4

4

There are a couple of different strategies possible, which all can be tailored further if necessary.

  1. Copy one character at a time into the destination, scanning ahead for find and inserting replace when found, the original character when not found;
  2. Copy one word at a time into the destination, scanning ahead for 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;
  3. Use library functions to scan for the find text.

Which strategy to use depends on further (unmentioned) requirements, such as

  1. case sensitive?
  2. whole word only?
  3. replace once only, or all occurrences?
  4. can either 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]
Jongware
  • 22,200
  • 8
  • 54
  • 100
3

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.

R Schultz
  • 486
  • 5
  • 10
1
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] ="This is a simple string made with simple code";
  char * pch;
  int i=0,count=0;
  for(i=0;i<strlen(str);i++){
    if(str[i]=='s'&& str[i+1]=='i'&&str[i+2]=='m'&&str[i+3]=='p' && str[i+4]=='l' && str[i+5]=='e'){
        count++;
      }
  }
  for(i=1;i<=count;i++){
    pch = strstr (str,"simple");
    strncpy (pch,"sample",6);
  }

  puts (str);
  return 0;
}
Suvam Roy
  • 963
  • 1
  • 8
  • 19
0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
  
// Function to replace a string with another string

char* replaceWord(const char* s, const char* oldW,
                  const char* newW)
{
    char* result;
    int i, cnt = 0;
    int newWlen = strlen(newW);
    int oldWlen = strlen(oldW);
  
    // Counting the number of times old word occur in the string
    for (i = 0; s[i] != '\0'; i++) {
        if (strstr(&s[i], oldW) == &s[i]) {
            cnt++;
  
            // Jumping to index after the old word.
            i += oldWlen - 1;
        }
    }
  
    // Making new string of enough length
    result = (char*)malloc(i + cnt * (newWlen - oldWlen) + 1);
  
    i = 0;
    while (*s) {
        // compare the substring with the result
        if (strstr(s, oldW) == s) {
            strcpy(&result[i], newW);
            i += newWlen;
            s += oldWlen;
        }
        else
            result[i++] = *s++;
    }
  
    result[i] = '\0';
    return result;
}
  
// Driver Program
int main()
{
    char str[] = "xxforxx xx for xx";
    char c[] = "xx";
    char d[] = "Geeks";
  
    char* result = NULL;
  
    // oldW string
    printf("Old string: %s\n", str);
  
    result = replaceWord(str, c, d);
    printf("New String: %s\n", result);
  
    free(result);
    return 0;
}
Tawhid Monowar
  • 126
  • 1
  • 6
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Tyler2P Oct 21 '21 at 16:54