Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
708 views
in Technique[技术] by (71.8m points)

removing all sub strings of a string in C

Ive been trying to remove all occurrences of a substring from a given string but my code has a bug which I don't know how to resolve. When two substrings are back-to-back my code can only remove one of them.

This is my code:

void removeSub(char *str, char *sub, char *new) {
    int len = strlen(sub);
    char *subp = strstr(str, sub);
    int position = subp - str;
    for (int i = 0; i <= strlen(str); i++) {
        if (i >= position && i < position + len) {
            continue;
        }

        if (i == position + len - 1) {
            // update position
            subp = strstr(str + i - 1, sub);
            position = subp - str;
        }
        
        char ch = str[i];
        strncat(new, &ch, 1);
    }
}

a quick explanation of code: I copy the string char by char into another string(new) and whenever I see the substring along the way my code continues the loop and does nothing. when a substring is passed I relocate the next substring. (I know this isn't very efficient but I'm new and don't know many ways and functions)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Your code has multiple issues:

  • the loop for (int i = 0; i <= strlen(str); i++) is very inefficient as the length of str is recomputed at each iteration of the loop. You should simply write:

    for (int i = 0; str[i] != ''; i++)
    
  • when you skip the matched substring, the character after it is copied and i is incremented in the loop so the next occurrence is not tested correctly.

  • the code to append a single character is inefficient: instead of strncat(new, &ch, 1); you should have a pointer to the end of the destination string and write *p++ = str[i]; and set the null terminator after the end of the loop.

Here is a modified version:

#include <string.h>
// remove all occurrences of sub in str into destination buffer new
// return a pointer to the destination string
char *removeSub(cont char *str, const char *sub, char *new) {
    char *p = new;
    size_t len = strlen(sub);
    if (len > 0) {
        const char *subp;
        while ((subp = strstr(str, sub)) != NULL) {
            memcpy(p, str, sub - str);
            p += sub - str;
            str = sub + len;
        }
    }
    strcpy(p, str);
    return new;
}

And an alternative without library calls:

// remove all occurrences of sub in str into destination buffer new
// return a pointer to the destination string
char *removeSub(cont char *str, const char *sub, char *new) {
    char *p = new;
    while (*str) {
        if (*str == *sub) {  /* potential substring match */
            for (size_t i = 1;; i++) {
                if (sub[i] == '') {  /* substring match */
                    str += i;
                    break;
                }
                if (str[i] != sub[i]) {
                    *p++ = *str++;
                    break;
                }
            }
        } else {
            *p++ = *str++;
        }
    }
    *p = '';
    return new;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...