Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing Words inside string in C

Tags:

c

string

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

}

like image 202
Matan Avatar asked Feb 11 '23 11:02

Matan


2 Answers

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]
like image 131
Jongware Avatar answered Feb 14 '23 10:02

Jongware


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.

like image 33
R Schultz Avatar answered Feb 14 '23 10:02

R Schultz