1

For example, I want to replace abc in 123abc890 with xyz. How would I do this without using #include <string.h>.

I tried attempting this by creating a new string, and with the help of a for loop, I would copy every character into the new string. However, I couldn't seem to find out how to go about doing this. Any method is fine, however I cannot use #include <string.h>.

char str1[] = "123abc890";
char str2[] = "abc";
char str3[] = "xyz";
char new_string[50];

for (int i = 0; str1[i] != '\0'; i++) {
    if (str1[i] == str2[i]) {
        for (int j = 0; str2[j] != '\0'; j++) {
            if (str1[i+j] != str1[i+j]) {
                break:
            }
            new_string[i] = str3[i];
        }
    }
    new_string[i] = str1[i];
}

FYI I am very new to C, so beware of some very clumsy code.

  • 1
    Please show a [mcve]. This is just a code fragment that cannot be compiled. – Jabberwocky Feb 04 '21 at 20:54
  • 1
    Break the problem up into smaller steps. Write functions for those where it makes sense. For example, start by writing a function that takes `str1` and `str2` and then returns the first index (if any) in `str1` that matches `str2` - i.e, basically rewrite `strstr`. – kaylum Feb 04 '21 at 20:54
  • 5
    Also if you are not allowed to use functions in `string.h` you can write your own versions of them. Many of them are one or two liners. – Jabberwocky Feb 04 '21 at 20:55
  • 2
    Does this answer your question? [What function is to replace a substring from a string in C?](https://stackoverflow.com/questions/779875/what-function-is-to-replace-a-substring-from-a-string-in-c) – Silidrone Feb 04 '21 at 20:56
  • Try working out the algorithm on paper first. The loop and indices here don't make much sense. Just because `str1[i] == str2[0]` doesn't mean you have a full substring, so if you're going to rush ahead and start copying that substring as if you did, be prepared to undo it when the entire substring doesn't match. Write a helper that checks the full substring match between str2 and str and try it on every index of str1. When it returns true, you're safe to copy str2 over to the destination, else copy str1's character. – ggorlen Feb 04 '21 at 21:00
  • I would arrange your code like this: (1) Write your own version of `strlen()`. (2) Write a function that searches for `str1` inside of `str2`, returning the index if found, or -1 if not. (This is like the standard `strstr` function, but using indexes instead of pointers.) (3) Use your function from (1) to find the length of "123abc890", and use your function from (2) to find the position of "abc" within it. Maybe also use your function from (1) to check the lengths of "abc" and "xyz". – Steve Summit Feb 04 '21 at 21:42
  • (4) Now do some math to find the length of the initial string you want to copy from "123abc890" to your new string, and the position and length of the final portion. (5) Write your own version of the standard `strncat` function. Make sure that after copying `n` characters, it always null-terminates the destination. (6) Make sure your new, destination string is empty (contains one `'\0'`). (7) Make three calls to your function from (5) to copy the initial portion, the replacement portion, and the final portion to your destination string. – Steve Summit Feb 04 '21 at 21:44
  • I guess it looks kinda complicated when I describe it at that level of detail, but really, each of those steps should be do-able, and then they'll all fit together to solve your larger problem. – Steve Summit Feb 04 '21 at 21:45

1 Answers1

2

Your code is a good start, but there are many problems:

  • the test if (str1[i+j] != str1[i+j]) is always true
  • you copy incomplete fragments and fail to skip it after copying.
  • you forgot to null terminate the destination.

Here is a modified version:

#include <stdio.h>

char *str_replace(char *dest, const char *str1, const char *str2, const char *str3) {
    size_t i = 0, j, k = 0;
    
    // replacing substring `str2` with `str3`, assuming sufficient space
    while (str1[i] != '\0') {
        for (j = 0; str2[j] != '\0'; j++) {
            if (str1[i + j] != str2[j]) {
                break;
            }
        }
        if (str2[j] == '\0' && j > 0) {
            // we have a match: copy the replacement and skip it
            i += j;
            for (j = 0; str3[j] != '\0'; j++) {
                dest[k++] = str3[j];
            }
        } else {
            // copy the byte and skip it.
            dest[k++] = str1[i++];
        }
    }
    dest[k] = '\0';  // null terminate the destination
    return dest;
}

int main() {
    char new_string[50];
    printf("%s\n", str_replace(new_string, "123abc890", "abc", "abc"));
    printf("%s\n", str_replace(new_string, "123abc890", "abc", "xyz"));
    printf("%s\n", str_replace(new_string, "123abc890", "a", "xyz"));
    printf("%s\n", str_replace(new_string, "123abc890", "abc", ""));
    return 0;
}

Output:

123abc890
123xyz890
123xyzbc890
123890
chqrlie
  • 131,814
  • 10
  • 121
  • 189