pippepappe
pippepappe

Reputation: 11

C program to replace a word in a text by another given word

I need help with an exercise in C. This is what I tried to do, but it doesn't work.

int main()
{
    int i, leng;
    char phrase[DIM], word[DIM], word2[DIM];

    printf("Write a sentence\n>>");
    fgets(phrase, sizeof(phrase), stdin);

    printf("Enter the word you want to replace in the sentence\n>> ");
    fgets(word, sizeof(word), stdin);

    printf("What do you want to replace it with?\n>> ");
    fgets(word2, sizeof(word2), stdin);

    leng = strlen(phrase);

    for (i = 0; i < leng; i++) {
        if (phrase[i] == word) {
            phrase[i] = word2;
        }
    }
    printf("%s", phrase);
    ...

When I start it, these warnings appear:

assignment to ‘char’ from ‘char *’ makes integer from pointer without a cast [-Wint-conversion]

comparison between pointer and integer

Upvotes: 1

Views: 8426

Answers (4)

chqrlie
chqrlie

Reputation: 144715

This exercise is somewhat tricky because the resulting string may be much longer than the original one. Here are steps to achieve it:

  • get the original string in frase. fgets() is fine for this but remove the trailing newline.
  • get the word to replace parola.
  • get replacement word parola2.
  • in a loop: search and count the number of occurrences of parola in frase using strstr().
  • allocate an array of size strlen(frase) + count * strlen(parola2) - count * strlen(parola) + 1 with char *result = malloc(size).
  • in a second loop, starting at char *p = frase, *r = result;.
    • search for the next occurrence of parola with q = strstr(p, parola)
    • if found, append the character from p to q to the result using memcpy(r, p, q - p), then append parola2, update p to q + strlen(parola), r to r + (q - p) + strlen(parola2) and iterate
    • if not found, append the rest of the phrase to the result with strcpy().
  • return the result. the caller will be responsible for discarding this array with free(result).
  • there is one special to handle carfully: if parola is an empty string.

Here is a simple implementation:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *strreplace(const char *s, const char *w1, const char *w2) {
    size_t len = strlen(s);
    size_t len1 = strlen(w1);
    size_t len2 = strlen(w2);
    size_t size = len + 1;
    const char *p, *q;
    char *result, *r;

    if (len >= len1 && len1 != len2 && len1 != 0) {
        // count the number of occurrences of w1 in s
        for (p = s; (p = strstr(p, w1)) != NULL; p += len1)
            size = size + len2 - len1;
    }
    r = result = malloc(size);
    if (result == NULL)
        return NULL;
    if (len1 != 0) {  /* don't replace the empty string */
        for (p = s; (q = strstr(p, w1)) != NULL; p = q + len1) {
            memcpy(r, p, q - p);
            r += q - p;
            memcpy(r, w2, len2);
            r += len2;
        }
    }
    strcpy(r, p);
    return result;
}

#define DIM 100

int main() {
    char phrase[DIM], word[DIM], word2[DIM];
    char *result;

    printf("Write a sentence\n>> ");
    if (!fgets(phrase, sizeof(phrase), stdin))
        return 1;
    phrase[strcspn(phrase, "\n")] = '\0';  // strip the newline if any

    printf("Enter the word you want to replace in the sentence\n>> ");
    if (!fgets(word, sizeof(word), stdin))
        return 1;
    word[strcspn(word, "\n")] = '\0';  // strip the newline if any

    printf("What do you want to replace it with?\n>> ");
    if (!fgets(word2, sizeof(word2), stdin))
        return 1;
    word2[strcspn(word2, "\n")] = '\0';  // strip the newline if any

    result = strreplace(phrase, word, word2);
    if (result == NULL) {
        printf("memory allocation failure\n");
        return 1;
    }
    printf("%s\n", result);
    free(result);
    return 0;
}

Sample run:

>> Sarah e bellissima
Enter the word you want to replace in the sentence
>> e
What do you want to replace it with?
>> erava
Sarah erava beravallissima

If you want to only replace exact words, you must specify what a word is. You could use the same function as above but replace strstr with a function that locates a word inside a string such as this one:

char *findword(const char *s, const char *w) {
    size_t len = strlen(w);
    char *p;
    while ((p = strstr(s, w)) != NULL) {
        if ((p == s || p[-1] == ' ') && (p[len] == '\0' || p[len] == ' '))
            break;
        s = p + len;
    }
    return p;
}

Upvotes: 0

Luis
Luis

Reputation: 1293

Your need to treat word and word2 as char arrays.

        if (phrase[i] == word) {
            phrase[i] = word2;
        }

In this block phrase[i] has char type and word/word2 are char[]. Presumably, you want to test that the next strlen(word) characters at phrase[i] all match word (e.g. phrase[i + j] == word[j]). Similarly in terms of replacement, you probably want to replace strlen(word2) characters. Note that you will need to be careful here if the lengths of word and word2 are not the same; I will leave that to you but here's a hint: you may consider using new buffer (char[]) for the result.

Upvotes: 0

Rup
Rup

Reputation: 34408

You said this was an exercise, so here are instructions rather than a complete solution.

Our options are:

  1. replace the word in-place in phrase - this is do-able, but given we don't know for sure that word and word2 are the same length this is going to be slightly tricky, so let's pick another way
  2. make a new character array for the output string and assemble the string with replacements in this new array
  3. print the various parts of the output string as we go, and don't assemble them into a buffer.

In all cases what we want to do is to work through phrase

  • find the next instance of word in phrase
  • if there is one
    • copy / print everything from the last position up to the start of the word we've found
    • copy / print word2
    • advance our cursor past the end of the found word and start again
  • if there are no more instances of word
    • copy / print the rest of the string

The specific C string operations you need are

  • strstr - find the first instance of one string in another; returns the start of the found string, or null if not found
  • strcpy - copy a whole string to another place
  • strncpy - copy a given number of characters from one string to another

Let's consider the output buffer method, #2. To do that, you'll need to:

  • declare a new output buffer, e.g. char buffer[DIM].
  • declare input and output buffer cursors. It'll be easier to work with char* cursors, e.g. char* input = phrase; char* output = buffer;
  • loop
    • find the next instance of word starting at input using strstr, e.g. char* next_word = strstr(input, word);
    • if next_word != null
      • copy everything from input to next_word to output, and advance output to the end of the characters you've just copied
      • copy word2 to output, and advance output past the end of word2 that you've just copied
      • advance input to next_word plus the length of word
    • else (i.e. next_word == null)
      • copy everything after input to the end of phrase to output
  • print output as before.

Hope that makes sense!

Upvotes: 0

Arty
Arty

Reputation: 49

Since I think you want to change only a letter it's easier to not create a string for parola and parola2. (The space before the %c it's to "eat" the enter or it will jump that question.)

    int i, leng;
    char frase[100], parola, parola2;

    printf("Inserisci una frase\n>>");
    gets(frase);

    printf("Inserisci la lettera che vuoi sostituire della frase\n>> ");
    scanf("%c", &parola);

    printf("Con cosa vuoi sostituirla?\n>> ");
    scanf(" %c", &parola2);
    
    leng = strlen(frase);
    
    
    for(i=0;i<leng;i++){
        if(frase[i] == parola){
            frase[i] = parola2;
        }
    }
    
    printf("%s", frase);

Upvotes: 1

Related Questions