Search code examples
cstringmemmove

Why does memmove behave different when i want to replace a string at the first letter?


In the Code below, i don't understand, why i have to write memmove like this in the if statement when pos == 0 (when i want to replace at the first position of the string array) :

strlen(string1) - strlen(string2+1))

I think i don't understand how many bytes i have to choose for my memmove function.

What is the different between the if and the else statement?

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

void cleanup(char *string1, char *string2, int pos);
int indexe(char string1[], char string2[]);

int main() {
    char string1[100];
    char string2[100];

    printf("PUT YOUR STRING\n");
    scanf("%99s", string1);

    printf("WHICH LETTERS DELETE?\n");
    scanf("%99s", string2);

    printf("String1 vorher: %s\n", string1);


    while(strstr(string1, string2)){
            cleanup(string1, string2,indexe(string1, string2));
    }

    printf("String1 before: %s\n", string1);
    printf("String1 after: %d\n", strlen(string1));

    return 0;
}

void cleanup(char *string1, char *string2, int pos) {

    pos = pos - strlen(string2);


    if(pos == 0){
    memmove(&string1[pos], &string1[pos + strlen(string2)], strlen(string1) - strlen(string2+1));
    }
    else
    memmove(&string1[pos], &string1[pos + strlen(string2)], strlen(string1) - strlen(string2));

}


int indexe(char string1[], char string2[]){

    char *firstpos = string1;
    char *secondpos = strstr(string1, string2);



    int pos = secondpos - firstpos + strlen(string2);

    printf("deleted index: %d\n", pos);

    return pos;

}

output: dayhousedayhouse

NOTE: the code does what i want. I only want to understand why :)


Solution

  • You are specifying the target and source and then saying how many bytes to move.

    holidayhousedayhouse0
    ^   ^
    

    These are target and the source positions. Now how many bytes to move? You said

    strlen(string1) - strlen(string2+1)
    

    which is same as

    20 - 3 = 17
    

    That much byte is moved precisely. (The \0 is copied too).

    holidayhousedayhouse0
    ^   ^
    dayhousedayhouse0
    ^   
    |---------------|
         17 chars
    

    string2+1 - string2 points to the beginning of the array - which is th first character in the array (h) here. When you add 1 - it basically moves by the size to which it points to - size of char is 1 so it moves by 1 position. That's why you get the length of 3 as if you counted letters from the second letter o. (upto \0).


    The explanation provided above hints that the cleanup logic can be done simply using the if part's memcpy statement. The else part can be omitted.

    The code you have shown is overcomplicating things given the simple task. The removal logic can be uniform. This works.